65 fetch API

fetch (dall’inglese prelevare) è un’interfaccia che ci permette di manipolare le chiamate HTTP e parte della pipeline HTTP (struttura tecnologica della comunicazione), come costruire e manipolare le richieste o  processare le risposte . È molto simile all ‘ XMLHttpRequest, ma con dettagli e sfumature differenti. Una tra le varianti più importanti è che alcuni errori come il 404 o il 500 non provocano il failure della promise restituita da fetch. Infatti ritornano una promise risolta di cui è necessario controllarne lo stato verificandone gli headers.

I browser vecchi non supportano fetch, ma esiste una libreria chiamata polyfill che è possibile integrare che aggiunge la compatibilità per gli eventuali browser che non supportano fetch.

Entrando nel vivo, utilizziamo fetch per prelevare dati json, utilizziamo la piattaforma jsonplaceholder.typicode che mette a disposizione delle url che restituiscono dei dati in formato json fake, sono praticamente delle API per ottenere dati json per post e commenti da esempio .

Memorizziamo l’url dei post in una variabile

let postUrl = 'https://jsonplaceholder.typicode.com/posts/';

ora vediamo come prelevare questi dati via AJAX facendo una chiamata con fetch.

Chiamiamo la funzione globale dell’oggetto window.fetch passando l’url al quale possiamo aggiungere l’id del post, nel nostro caso passiamo l’id 1 che corrisponde al primo post. Conseguentemente invochiamo il metodo then per risolvere la promise di fetch, infatti fetch restituisce una promise. Creiamo una funzione result utilizzando una funzione freccia result come risultato della promise. Infine lanciamo catch per un eventuale reject della promise.

fetch(postUrl + 1 ).then( result => {
 .....codice
}).catch(err => {
    console.log(err);
})

La prima cosa da effettuare è vedere cosa ci restituisce la promise di fetch quando viene risolta mandando in log result:

console.dir(result);

e andiamo a verificare cosa visualizza il browser. Nell’inspector alla sezione network selezionando All e caricando la pagina vediamo il flusso della chiamata e della risposta. Navigando nel tab Headers, abbiamo lo stato della chiamata e nel tab Responce troviamo i dati restituiti del post in formato JSON . Nella sezione Console abbiamo invece tutta la risposta catturata dal nostro console.dir.

Analizzando l’oggetto della risposta in console, troviamo i body, che dobbiamo poi parsificare per avere accesso ai dati, abbiamo l’oggetto headers contenete la risposta, con i suoi metodi tipo append, delete, il Get per le verifiche , cicli…. Abbiamo anche la property ok

response.Headers.ok

Può restituire TRUE se la risposta è corretta. Stessa cosa per lo stato

response.Headers.status

se è 200 lo stato è corretto. Facciamo un controllo nel codice se il parametro ok è true, ci facciamo restituire il content type dal get

let postUrl = 'https://jsonplaceholder.typicode.com/posts/';

fetch(postUrl + 1 ).then( result => {
    if(result.ok) {
        console.log(result.headers.get('Content-Type'))
    }
}).catch(err => {
    console.log(err);
})

La risposta in console è

application/json; charset=utf-8

a questo punto possiamo verificare se il server ci risponde e restituisce col Get un tipo di contenuto, e se include un json col (usiamo il metodo js include) facciamo restituire il risult.json, che è un metodo del result.

if(result.ok) {
    if(result.headers.get('Content-Type').includes('application/json')) {
        return result.json();
    }
}

quindi se lo stato ok è true e il metodo get include ci restituisce un json, restituiamo un il metodo json() di result, che è uno dei tanti metodi di result. Se una delle condizioni non è soddisfatta, solleviamo un’eccezione col throw

if(result.ok) {
    if(result.headers.get('Content-Type').includes('application/json')) {
        return result.json();
    }
    throw new Error('La risposta sul tipo non è un JSON');
}

a questo punto, una volta che i controlli sono andati a buon fine, possiamo risolvere la promise col metodo then ecco tutto il codice:

let postUrl = 'https://jsonplaceholder.typicode.com/posts/';

fetch(postUrl + 1 ).then( result => {
    if(result.ok) {
        if(result.headers.get('Content-Type').includes('application/json')) {
            return result.json();
        }
        throw new Error('La risposta sul tipo non è un JSON');
    }
}).then( json =>{
    console.log(json)
}).catch(err => {
    console.log(err);
})

Bisogna ricordarsi sempre quando si utilizza fetch di verificare che lo stato ok sia true oppure che lo status sia tra 300 o 300.

Qualora la risposta, non fosse un json, ma latri tipi di dati, vome text, blob, formatData… esistono altri metodi, visionabili nella documentazione di fetch.