Javascript draait in een loop vanwege JSON-string?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

- Ariën  -
Beheerder

- Ariën -

22/10/2017 23:00:27
Quote Anchor link
Ik heb hier een stukje AJAX-code die wat coordianten uit een API ophaalt, en verwerkt in Google Maps met een timertje die elke 5 seconden ververst. En zodoende heb je dus een mooie voertuigtracker... als het werkt.

Echter is het probleem dat deze in een recursieve loop draait, geeft de debugger weer, en inderdaad wordt er een hoop geheugen gebruikt.

Dus, het werkt niet. En het ligt aan de format van de JSON-string, heb ik het idee.
Als deze gewoon leeg is dan laad hij het script prima in (en uiteraard op de 0,0 locatie). Maar met onderstaande JSON-string in de request gaat hij dus voluit op zijn plaat op lijn nummer 15.

Wat gaat er mis?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
{"1234":{"DateGPS":"2017-10-22T22:55:45+02:00","DateReceived":"2017-10-22T22:55:46.071+02:00","Longitude":5.74551,"Latitude":52.01425,"Speed":139,"DOP":0,"VehicleNumber":"1234","VehicleType":"Sprinter","TrainNumber":"4321"}}


Het stukje (ingekortte) code


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function getCoords() {
        $.ajax({
        url: "api.php",
        type: "GET",
        cache: false,
        data: {
            action : "trainset",
            number : '1234'
        },
        dataType: "text",
        success: function(returnedData) {
            alert(returnedData);
            var jsondata = jQuery.parseJSON(returnedData);
              console.log('Joehoe'+returnedData);
              var coords = jsondata.Latitude+','+jsondata.Longitude;
              alert(coords);
              //console.log('Lat: '+jsondata.Latitude);
              var coordsArray = coords.split(",");
              moveMarkerMap(coordsArray[0], coordsArray[1]);
              setTimeout(getCoords, 5000);
              
              
        },
        done: function(data) {
            //setTimeout(getCoords, 5000); // hier werkt hij niet.
        }     
         });
    }

function moveMarkerMap(lat,lon) {
        var newLatLang = new google.maps.LatLng(lat,lon);
        map.panTo(newLatLang);
        marker.setPosition(newLatLang);
    }      
Gewijzigd op 22/10/2017 23:02:24 door - Ariën -
 
PHP hulp

PHP hulp

24/04/2024 14:08:28
 
- SanThe -

- SanThe -

22/10/2017 23:31:49
Quote Anchor link
Geen verstand van jquery, maar zo is ie normaal in js:
setTimeout(function(){ getCoords(); }, 5000);
Gewijzigd op 22/10/2017 23:32:09 door - SanThe -
 
- Ariën  -
Beheerder

- Ariën -

22/10/2017 23:48:28
Quote Anchor link
Maar daar ligt het niet aan, want als ik die wegcomment gaat 'ie wel goed, althans... hij 'loopt' dan niet.

Het gaat gewoon fout in die returnedData en de JSON-string.
Gewijzigd op 22/10/2017 23:49:00 door - Ariën -
 
Rob Doemaarwat

Rob Doemaarwat

22/10/2017 23:54:43
Quote Anchor link
Is het probleem niet dat je zowel op de success als de done een nieuwe timer start (dus 2x). Die starten beide ook weer 2 nieuwe timers, enz. Gaat best hard.

Tevens: waarom gebruik je niet dateType: 'json', hoef je niet met parseJSON() aan de slag.
 
Thomas van den Heuvel

Thomas van den Heuvel

22/10/2017 23:58:20
Quote Anchor link
Waarom geef je niet "json" aan bij de dataType parameter? Hoef je het ook niet te parsen lijkt mij?

EDIT: @Rob was me voor
Gewijzigd op 22/10/2017 23:58:58 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

22/10/2017 23:58:22
Quote Anchor link
@Rob: Bij het done-event is hij ook weggecomment, omdat die daar niet werkte.

Maar als ik dataType JSON gebruik, hoe kan ik dan de data uit de JSON-string apart oproepen i.p.v. JSONparse?

Maar waarom gaat hij puur op zijn plaat op deze JSON-string dan? Dat snap ik echt niet.
Voorheen had deze techniek ook geen moeite, dus ik kan wel overstappen naar JSON als dataType, maar dat is nog geen oplossing voor dit probleem, lijkt mij.

Edit:
Hij loopt niet meer met dataType JSON. :-)
Inmiddels heb ik dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
success: function(returnedData) {
    alert('Joehoe'+returnedData);
    var coords = returnedData.Latitude+','+returnedData.Longitude;
    alert(coords);

    /*
    console.log('Lat: '+jsondata.Latitude);
    var coordsArray = coords.split(",");
    moveMarkerMap(coordsArray[0], coordsArray[1]);
              setTimeout(getCoords, 5000);
    */
        },


Echter geeft hij aan dat coords undefined is.
Waarom?
Gewijzigd op 23/10/2017 00:18:26 door - Ariën -
 
Rob Doemaarwat

Rob Doemaarwat

23/10/2017 00:15:52
Quote Anchor link
Maar nog steeds dezelfde fout?

Als je beide setTimeouts() even weglaat? Nog steeds zelfde probleem?
En als je regel 15 t/m 19 weglaat? Nog steeds zelfde probleem? Je zit op regel 15 nl wel twee floats te concatten, misschien gaat dat mis, en triggert dat de verdere ellende (error handler ergens)?


Als je dataType: 'json' meegeeft is je returnedData meteen al JSON. Hoef je dus niks voor te doen.
 
- Ariën  -
Beheerder

- Ariën -

23/10/2017 00:17:49
Quote Anchor link
Zie mijn ninja-edit boven je ;-)
Ik ben een stapje verder, en volgens mij het laatste stapje tot het werkend is.

Nu nog die undefined ...

Er komen om vage redenen geen coordinaten door, dus gaat die andere setTimeout ergens dus onderuit.
Gewijzigd op 23/10/2017 00:20:35 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

23/10/2017 00:20:46
Quote Anchor link
De Latitude en Longitude zitten nog in een subarray subojbect van het treinnummer als de JSON-snippet uit je oorspronkelijke bericht nog steeds van toepassing is. Deze zul je dan daar uit moeten peuteren.
Gewijzigd op 23/10/2017 00:36:31 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

23/10/2017 00:21:53
Quote Anchor link
Aha, nu zie ik het. En hoe bewerkstelligen we dat met jQuery?
 
Thomas van den Heuvel

Thomas van den Heuvel

23/10/2017 00:54:16
Quote Anchor link
Hm, als ik mij niet vergis is die API-respons nogal onhandig opgezet. Immers, je vraagt iets van een specifieke trainset op. Vervolgens wordt de data teruggegeven als de waarde van een property... Waarom niet meteen de data? :/

Krijg je ooit waarden terug van meerdere trainsets? Want properties hebben geen vaste volgorde, dus je zult dan echt aan het trainset-nummer moeten refereren om de juiste data terug te krijgen :/.

Ik weet ook niet of properties de naamgeving van variabelen moeten volgen (lijkt mij van wel?), dus als dat echt letterlijk "1234" is (zal wel niet?) dan is dat technisch gezien niet eens een toegestane constructie.

Als die "1234" een soort van tekst is die voldoet aan de naamgeving van een variabele (bijvoorbeeld "blaat"), dan zou je hier aan kunnen refereren via returnedData.blaat.Longitude (dus gewoon een object syntax), maar dan moet je callback-functie wel dit nummer kennen. Je zou twee vliegen in een klap kunnen slaan door hier een parameter van te maken in je getCoords() functie, zodat deze ook meteen wat dynamischer wordt?
Gewijzigd op 23/10/2017 00:55:01 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

23/10/2017 01:05:22
Quote Anchor link
Ja, ik kan ook data krijgen van meerdere trainsets, als je op het TrainNumber (Lijnnummer/Treinnummer) filtert. (m.a.w. treinen kunnen ook gekoppeld rijden).

En die 1234 is in dit geval een (fictief) VehicleNumber van een trein, en geen dummy iets.
Maar opsich lijkt mij dat die eerste array overbodig is, zodat je per trainset een enkele array hebt.
Dus dat lijkt mij logischer.
 
Marthijn Buijs

Marthijn Buijs

23/10/2017 01:08:49
Quote Anchor link
Misschien kan je iets met de JavaScript functie clearTimeout.
 
- Ariën  -
Beheerder

- Ariën -

23/10/2017 01:17:57
Quote Anchor link
Daar ga ik naar kijken, maar het probleem zit hem echt in de JSON string, en die (onnodige sub-array)

Ik duik even de code in om die array te genereren:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$arr
= json_decode($content,true);
        //$newfeed = array();
    foreach($arr as $data) {
        $newfeed[$data['Trackee']]['DateGPS'] = $data['DateGps'];
        $newfeed[$data['Trackee']]['DateReceived'] = $data['DateReceived'];
        $newfeed[$data['Trackee']]['Longitude'] = $data['Longitude'];
        $newfeed[$data['Trackee']]['Latitude'] = $data['Latitude'];
        $newfeed[$data['Trackee']]['Speed'] = $data['Speed'];
        $newfeed[$data['Trackee']]['DOP'] = $data['Dop'];
        $newfeed[$data['Trackee']]['VehicleNumber'] = strip_additionals($data['Trackee']);
        $newfeed[$data['Trackee']]['VehicleType'] = getVehicleTypesByVehicleNumber(strip_additionals($data['Trackee']));
        $newfeed[$data['Trackee']]['TrainNumber'] = $data['Number'];
        $newfeed[$data['Trackee']]['Status'] = getTrainStatus($data['Number']);
    }

    $feed = json_encode($newfeed);
    return $feed;
?>

Hoe maken we er dan per trainset een enkele array van?
$arr is het orgineel, en ik wil de API dus wijzigen met extra inhoud, en andere aanduidingen. En die commented array helpt ook niet.

Hmmm....
Gewijzigd op 23/10/2017 01:33:54 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

23/10/2017 03:23:43
Quote Anchor link
Quote:
Hoe maken we er dan per trainset een enkele array van?

Opvragen via specifiek $data['Trackee'] en dan alleen een array/object teruggeven met DateGPS, DateReceived, ... en alle andere informatie die je er in wilt stoppen?
 
- Ariën  -
Beheerder

- Ariën -

23/10/2017 09:16:22
Quote Anchor link
Dat doe ik toch ook?
Want ik wil namelijk een heel nieuwe array opbouwen, dan die van $data.
En dus geen array in een array.

Dus eigenlijk moet er dan dit bijv. kunnen uitkomen (in dit geval zijn dat er twee trainsets, wat natuurlijk ook een enkele kan zijn):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
[{"DateGps":"2017-10-23T09:20:00+02:00","DateReceived":"2017-10-23T09:20:00.864+02:00","Longitude":5.17141,"Latitude":52.16514,"Speed":115,"DOP":0,"VehicleNumber":"2459","TrainNumber":"5726"},{"DateGps":"2017-10-23T09:19:58+02:00","DateReceived":"2017-10-23T09:19:59.218+02:00","Longitude":4.67238,"Latitude":52.3829,"Speed":18,"DOP":0,"VehicleNumber":"2978","TrainNumber":"5420"}]

En dit stelt dus een enkele array voor per trainset, en geen multi-dimensionale en ook geen key.
Maar hoe krijg ik dat dan voor elkaar? Ik krijg dan constant die key er steeds bij :/

Update 1:
Ik kreeg vanmorgen in mijn schoot geworpen van een vriend dat ik in een enkel element in de foreach een array moet aanmaken met die trein-properties en values. Erg logisch, en 'that was the trick'!

Update 2:
Echter bij het filteren op een waarde van een propterty/argument gaat het ook mis:
https://3v4l.org/CnbbQ
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
$array
= json_decode($json,true);
$resulted_array = array_filter($array,function($v){ return ($v['Trackee'] == '2469');});

echo json_encode($resulted_array);
?>


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    {"11":{"DateGps":"2016-08-04T00:36:54+02:00","DateReceived":"2016-08-04T00:36:55.813+02:00","Longitude":4.3087,"Latitude":52.0525,"Track":354,"Speed":50,"Dop":1,"Trackee":"2469","Bps":"MC 112-63,3","Number":"15184"}}


Toevoeging op 23/10/2017 23:33:20:

Update 3:

Het probleem is getackeld, en de key is eruit gehaald zodat de AJAX-request in getCoords() de boel beter kan uitlezen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
$json_to_array = json_decode($json, true);
$resulted_array = array_values(array_filter($json_to_array,function($v){ return ($v['VehicleNumber'] == $_GET['VehicleNumber']);}));
if (count($resulted_array) == 1) // Als hij niet 1 is is het item niet gevonden...
    $resulted_array = $resulted_array[0];
    echo json_encode($resulted_array);
?>



Thnx to all voor de adviezen :-)
Gewijzigd op 23/10/2017 23:34:00 door - Ariën -
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.