Problema con richiesta-risposta http

di il
15 risposte

Problema con richiesta-risposta http

Salve a tutti,
sono un neofita di Js. Prima di andare al cuore del problema vi illustro cosa devo fare.
Ho un file di testo su cui ogni x secondi vengono scritti ordinatamente alcuni dati, principalmente coordinate.
Il mio obiettivo è quello di inserire ad ogni aggiornamento del file di testo, un marker su una mappa di Google per ogni coppia di coordinate letta dal file.
Per fare tutto questo ho ovviamente progettato un web server locale.
Dunque i file da programmare sono due: un file .js relativo al server locale e un altro file .html in cui si interviene sulla mappa.
Il file .js è questo (ometto l'implementazione della funzione che processa i dati presi dal file):

const express = require('express');
const fs=require('fs');
const app = express();

app.use(express.static('public'))

const port = 3000;

const ip = '127.0.0.1';

app.get('/', function(req, res)
{
 res.sendFile(__dirname+'/index.html'); //risponde con il file "index.html");
})

app.get('/prova', function(req,res){

  fs.readFile("public/data_set.txt", "utf-8", function(err,data){
    if (err) {
      console.log(err);
    }
    else{
      //codice relativo all'estrazione dei dati di interesse dal file (è corretto).  
        
        //creazione oggetto con chiavi e valori corrispondenti
        let misure={day:calendario, hour:ora, latitude: latit, longitude:long};     
        
        //risposta HTML contenente l'oggetto "misure"
        res.send(misure);
      }
    }
  })       
});
i problemi invece si presentano sul file .html con cui il server risponde al client quando instaura connessione con localhost.
Il file .html è il seguente:

<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
       }
    </style>
  </head>
  <body>
    <h1>PERCORSO</h1>
    <script src=personale></script>
    <div id="map"></div>
   
    <script>
        
        // Inizializzazione e aggiunta mappa
        function initMap() {   
          let città = {lat: 53.789132, lng: 33.350162};  
        
          // mappa centrata su città
          let map = new google.maps.Map( document.getElementById('map'), {zoom: 10, center: città});
        }
        
     //chiamata Ajax HTTP di tipo GET        
        let loop = setInterval($.get(percorso file .js, function(data){
          
          
          console.log(data);
          
          let latitude=data.latitude;
         
          let longitude=data.longitude;
          
          let coords={ lat: latitude, lng: longitude };     
          
          let marker = new google.maps.Marker({position: coords, map:map}); 
          
          }),500);       
        
    </script>
    <script async defer src=myGoogleApiKey></script>
    
  
  </body>
</html>
in pratica ogni 500 ms viene effettuata una chiamata Ajax di tipo get che dovrebbe "riferire" al server di leggere nuovamente l'ultima riga del file di testo per vedere se ci sono nuove coordinate.
Aprendo il browser all'indirizzo localhost:3000 mi si presentano due errori:
1)http://127.0.0.1:3000/favicon.ic not found.
2) compare un errore ad ogni ciclo di "setInterval" che mi dice "missing ] after element list" in corrispondenza della funzione setInterval.

Qualcuno può darmi indicazioni o suggerimenti per risolvere i problemi?

15 Risposte

  • Re: Problema con richiesta-risposta http

    Ciao fiji,
    Intanto benvenuto nel forum!
    Per ricevere aiuto più facilmente sarebbe utile se modificassi il tuo post circondando il codice con il tag corrispondente (nella barra degli strumenti dell'editor di testo è il bottone con il simbolo </>).

    Un punto che ho notato che potrebbe essere un problema, è nella creazione dell'interval. Prova a spostare la tua richiesta jQuery dentro ad una funzione a freccia:
    
    let loop = setInterval(() => {
    	$.get(percorso file .js, function(data){
    		console.log(data);
    	}
    }, 500);
    
    Questo perché il primo parametro di setInterval deve essere una funzione, mentre se esegui il get direttamente questo verrà eseguito solo la prima volta e verrà passato all'interval il valore di ritorno, che dalla documentazione sembra essere un jqXHR.

    Fammi sapere se ti è stato utile
  • Re: Problema con richiesta-risposta http

    Grazie mille per la risposta!
    Ho seguito il tuo consiglio ed ora quei continui messaggi di errore non compaiono più. Resta però il fatto che l'errore 1) rimane e che quindi non compare nessun marker.
  • Re: Problema con richiesta-risposta http

    Ciao Fiji,
    Grazie mille per aver formattato il codice, adesso si riesce a vedere molto meglio!
    Il 1° errore che dicevi, quello del file "favicon.ico" not found, non è rilevante, perché indica solo che il browser non è riuscito a trovare la favicon, cioè l'immagine che viene mostrata affianco al nome del sito nelle tab del browser.

    Il vero problema è che quando usi l'API di Google Maps per aggiungere il marker, gli passi come parametro la variabile "map". Questa variabile viene inizializzata nella funzione "initMap" usando il codice:
    
    let map = new google.maps.Map(...);
    
    E' importante ricordare che se si usa il termine "let" stiamo dichiarando una variabile solo nel blocco di codice attuale. Ciò significa che quella variabile esisterà solo nell'ambito di quella funzione.
    Un metodo (premetto subito che alcuni mi spareranno per averlo detto) è quello di utilizzare una variabile globale. Questo significa dichiarare la variabile map fuori da tutte le funzioni senza dargli valore, e poi inizializzarne il valore dentro alla funzione initMap.

    Utilizzare una variabile globale può creare problemi per il futuro durante lo sviluppo del codice. Comunque, vedo che è questo il metodo che ti fanno usare nella documentazione di google, quindi non biasimatemi

    Un modo per racchiudere tutto in uno scope separato potrebbe essere quello di usare una closure impostando direttamente la funzione sull'oggetto 'window':
    
    ( () => {
    	let map = null;
    	
    	window.initMap = function () {
    	
    		let città = {lat: 53.789132, lng: 33.350162};  
              	// mappa centrata su città
              	map = new google.maps.Map( document.getElementById('map'), {zoom: 10, center: città});
    	}
    	
    	// Resto del codice per l'aggiunta del marker ...
    })()
    
    In questo modo l'api di google dovrebbe riuscire a trovare comunque la funzione initMap. Se questo codice ti dà problemi perché non trova la variabile "google" allora prova a togliere la prima e l'ultima riga del codice sopra, lasciando solo il codice all'interno della closure e impostando quindi delle variabili globali.
  • Re: Problema con richiesta-risposta http

    Ho effettuato le modifiche da te suggerite. Ho semplicemente impostato "map" come variabile globale.
    Il problema però resta.
    Nel file .html, quando la funzione setInterval viene chiamata ogni x ms la risposta alla richiesta HTTP non viene elaborata correttamente (o non viene elaborata affatto).
  • Re: Problema con richiesta-risposta http

    Ok...
    Nel loop tu fai un console.log dei dati. I dati che vengono visualizzati ti sembrano corretti?

    Può esserti utile imparare come fare il debug di javascript dalla tab "sources" degli strumenti di sviluppatore. Questo è un collegamento ad una guida (in inglese) di Google su come utilizzarli, sicuramente ti torneranno utili anche per il futuro
  • Re: Problema con richiesta-risposta http

    Il console.log l'ho inserito proprio per verificare se i dati fossero ricevuti e infatti non visualizzo nulla.
    L'unica cosa che so è che indirizzandomi su "localhost:3000/prova" mi vengono mostrati tutti i "campi" e dati dell'oggetto "misure" presente nel file .js.
  • Re: Problema con richiesta-risposta http

    Molto strano che tu non riceva indietro nessun tipo di dato...

    Qualche altro test che puoi fare:

    1 - Dalla console degli sviluppatori, dirigiti nella tab "Network". Qui vedi tutte le richieste che vengono effettuate. Assicurati che ogni 500ms ne compaia una nuova (dato che è quella la tempistica del setInterval). Se non ne vedi significa che c'è qualcosa di sbagliato nell'inizializzazione del setInterval o del get di jquery. Cliccando sulla richiesta ti darà anche utili informazioni (ti dice se è fallita o no e che dati sono stati ritornati)

    2 - Sempre nella console, andare nella tab "Sources". Nel selettore di file sulla sinistra, seleziona il file html che contiene il codice del loop. Clicca sul numero della riga dove inizializzi il loop e sul numero della riga dove hai inserito il get di jquery (questo creerà una specie di segnalibro blu in quel punto). Ora conviene ricaricare la pagina; l'esecuzione del codice javascript si fermerà in quei punti, in questo modo ti assicurerai che quelle sezioni di codice vengano eseguite. Una volta che si ferma sulla riga, se vuoi che riprenda l'esecuzione devi premere sul pulsante blu che ha l'icona del "play".

    Se vedi che il loop non viene eseguito o che il get non funziona, potresti riscrivere qui il codice che hai in questo momento? (con le ultime modifiche incluse). Solo quello del frontend, non del server, dato che abbiamo definito che funziona.

    Potresti anche fare una foto ai devtools con la schermata "Network" aperta (dopo qualche secondo che hai ricaricato la pagina). Potrebbe essere molto utile
  • Re: Problema con richiesta-risposta http

    Avevo già controllato se le richieste comparissero. Modificando la funzione "setInterval" come mi avevi suggerito in precedenza nessun oggetto viene rilevato dal "console.log" interno al "loop".
    Oltre alle richieste relative a Google Maps (tutte a buon fine), c'è una sola richiesta di tipo GET al dominio 127.0.0.1:3000, file "/".
    Ho utilizzato anche i breakpoint per verificare quali parti del codice non vengono eseguite ed è soltanto il "loop".
    Il codice è:
    let loop = setInterval(()=> $.get(percorso file .js, function(data,status){
              
              
              let latitude=data.latitude;
             
              let longitude=data.longitude;
              
              let coords={ lat: latitude, lng: longitude };
              
              let calendario=data.day;
              
              let ora=data.hour;
              
    
              
              marker = new google.maps.Marker({position: coords}); 
              marker.setMap(map);
              
              
              }),500);
  • Re: Problema con richiesta-risposta http

    Guarda, trovo che sia molto strano che il loop non venga inizializzato...
    Ho provato a fare un pen con una situazione simile (solo che faccio una richiesta ad un placeholder json e non uso le api di GMaps), e il loop viene eseguito correttamente...

    Una cosa che potresti provare (e che sarebbe forse meglio in ogni caso) è quella di spostare il setInterval alla fine della funzione initMap. La mappa viene inizializzata correttamente, giusto? In quel modo sei sicuro che quel codice verrà eseguito e che la variabile "map" sarà inizializzata
  • Re: Problema con richiesta-risposta http

    Il loop viene inizializzato. Il problema è che la chiamata $.get non riceve nulla come risposta dal server.
    Spostando il setInterval in "initMap" succede esattamente lo stesso.
    La mappa viene visualizzata correttamente. Il problema è tutto nella risposta alla richiesta HTTP.
  • Re: Problema con richiesta-risposta http

    A questo punto direi che il javascript frontend non è il problema...
    Hai provato a replicare la richiesta che trovi sugli strumenti di sviluppatore con un altro software?
    Per esempio, se sei su linux (o se hai il WSL) potresti provare con il seguente comando da terminale:
    curl http://127.0.0.1:3000/prova
    (Mi sembra fosse questa la route che hai impostato nel server con express)

    Altrimenti per effettuare e analizzare in modo più completo la richiesta, io in genere utilizzo postman, anche se all'inizio potrebbe sembrare complicato poi torna molto utile per testare le API.
    Ci sono molti metodi per farlo, quindi valuta tu come ti trovi più comodo.

    Se hai il server aperto su un terminale, puoi anche provare a vedere se ti viene loggato qualcosa lì. A volte vengono segnalati degli errori o informazioni utili
  • Re: Problema con richiesta-risposta http

    Ho provato da cmd e mi ritornano esattamente i dati del file.
    Ora mi è venuto un dubbio, quando effettuo la chiamata $.get(...) devo specificare che mi interessano i dati restituiti da "127.0.0.1/prova". Nell'url da inserire in $.get devo tener conto in qualche modo del "/prova"?
  • Re: Problema con richiesta-risposta http

    Ciao fiji,
    Sì, nel metodo $.get bisogna inserire il persorso completo della risorsa che viene richiesta. Questo percorso dipende dalle impostazioni del tuo server, ma da quanto vedo nel primo messaggio che hai inviato, sembrerebbe che il server node giri sull'ip 127.0.0.1 (locale) e la porta sia la 3000. Inoltre, mi sembra che tu leggi i dati quando la route richiesta è '/prova'.
    Quindi il primo parametro del $.get dovrebbe assomigliare a qualcosa come:
    
    $.get( "http://127.0.0.1:3000/prova" , ... 
    
    (che poi dovrebbe essere lo stesso che hai richiesto dalla cmd)
  • Re: Problema con richiesta-risposta http

    Tutto risolto!
    Adesso funziona alla perfezione!
    Grazie mille per la pazienza e per i consigli!
Devi accedere o registrarti per scrivere nel forum
15 risposte