11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour, j'aimerais juste avoir un petit coup de main (sans attendre de votre part qu'on me mâche le boulot), mais je bute depuis plusieurs jours sur un problème et même en regardant des tutoriaux à droite et à gauche.. je n'arrive pas à trouver une issue .. Peut être ma façon de résonner qui est mauvaise après tout..

Voici mon code :


// REQUETE AJAX  JCDECAUX //

// Création de la variable pour la requête 
const url = 'https://api.jcdecaux.com/vls/v1/stations?contract=Toulouse&apiKey=APIKEY';

// Création de la classe contenant les informations des stations
class Map {
    constructor (name, address, position, banking, bike_stands, available_bike_stands, available_bikes, status) {
        this.name = name;
        this.address = address;
        this.position = position;
        this.banking = banking;
        this.bike_stands = bike_stands;
        this.available_bike_stands = available_bike_stands;
        this.available_bikes = available_bikes;
        this.status = status;
    }
}

// Création de la fonction concernant le requête
async function main () {

    const getStations =  await fetch(url)

    .then(res => {
        if (res.ok && res.status == 200) {
            console.log('SUCCES')
            return res.json()
        } else {
            console.log('NOT SUCCESSFUL')
        }
    })

    .then(data => {
        for (var i = 0 ; i < data.length ; i++) {  
            var markers  = L.marker(data[i].position).addTo(map)
        }
        

    })

    .catch(error => console.log('Une erreur est survenue !'))

    console.log()
}

main();


Donc, du coup je reçois bien mon fichier JSON avec tout son contenu, et j'arrive à l'afficher avec un console log dans ma boucle for avec par exemple :
console.log(data[i].name)
Mais moi je voudrais surtout placer chaque éléments dans ma classe du genre ( this.name => data[i].name ), mais je n'arrive pas. J'ai regarder des cours sur les "SCOPES", je me doute qu'on vas me parler de variable locale, mais il y a surement un autre moyen non ?

Merci d'avance Smiley smile [/i]
Modifié par Sebastien40 (29 Jan 2020 - 03:01)
Modérateur
Et l'eau, là je n'ai pas vraiment la possibilité de vérifier ce dont je parle. Cela dit en lisant ton code, je pense que tu devrais plutôt te créer une class/objet statique. Ensuite dans le callback de ton ajax, tu hidrates ta class/objet. Sinon, si tu décidés de garder ta class telle qu'elle est, tu te crées des accesseurs (get, set). Je remarque que tu declares un class en plein code métier. Or, ça n'a rien à faire là. Mais je pense que l'organisation de ton code n'est pas encore optimale, n'est ce pas ?
Modifié par niuxe (29 Jan 2020 - 19:12)
Modérateur
limipl a écrit :
Et au lieu de résonner essaie de raisonner.

À qui tu t'adresses ?
Modifié par niuxe (29 Jan 2020 - 20:12)
Salut,

En effet comme l'évoque niuxe, il y a un petit souci de logique dans ton code...
Tu déclares une class Map que tu n'instancies jamais, normal ? Et de plus cette class ne reflète pas sa fonction. On pourrait s'attendre à ce qu'une class nommée Map gère la liste des stations, des éléments du DOM gérant l'affichage de la carte elle-même, des méthodes de zoom, de dézoome, mais pas le nom des stations ou leur position.
Il faudrait pour cela une autre classe nommée Station par exemple (hyper original Smiley smile ) qui s'occupe de chaque station. Et donc dans ta boucle suivant la réception des tes résultats il faut que tu instancies une Station en lui passant les data. Ensuite tu ajoutes chaque instance de Station à une propriété de ta classe Map (qui peut être statique si tu n'as qu'une seule carte sur ta page, mais bon...).

Ça peut donner un truc du genre :
class Map {
    /**
     * Ajoute une station à la liste des stations de la carte
     * @param station:Station
     */
    static addStation(station) {
        if(typeof this.stations === 'undefined' || this.stations.length === 0) {
            Map.stations = [];
        }
        Map.stations.push(station);
    }

    /**
     * Ajoute un marker sur la carte
     * @param station
     */
    static addMarkerToMap(station) {
        L.marker(station.position).addTo(Map.map).bindPopup(station.name);
    }

    /**
     * Initialisation de la carte
     */
    static initMap() {
        Map.fetchStationsUrl = 'https://my-json-server.typicode.com/korell/stations/stations';
        Map.stations = [];
        Map.markers = [];
        Map.currentZoom = 13;

        // Création de la carte dans le DOM
        Map.map = L.map('map').setView([43.595457,1.436616], Map.currentZoom);
        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(Map.map);
    }

    /**
     * Récupération des stations listées
     * @returns {Array}
     */
    static getStations() {
        return Map.stations;
    }

    /**
     * Récupération des données de l'API
     * @returns {Promise<T | never>}
     */
    static fetchStations() {
        return fetch(Map.fetchStationsUrl)
            .then(res => {
                if (res.ok && res.status === 200) {
                    return res.json();
                } else {
                    throw new Error(res.statusText);
                }
            })
            .then(data => {
                data.forEach(stationData => {
                    let station = new Station(stationData);
                    Map.addStation(station);
                })
                return {success: true};
            })
            .catch(error => {
                throw new Error(error);
            })
    }
}

class Station {
    /**
     * Instanciation de la classe avec les données de l'API
     * @param data
     */
    constructor(data) {
        this.name = data.name || '';
        this.position = data.position || '';
    }

    getName() {
        return this.name;
    }
    getposition() {
        return this.position;
    }
}


Map.initMap();

Map.fetchStations().then(data => {
    Map.getStations().forEach(station => {
        //station est une instance de Station
        Map.addMarkerToMap(station);
    })
}).catch(error => {
    console.log(error.message);
})

https://codepen.io/korell/pen/abzrRGe

Voilà !
Bonjour, et merci d'avoir pris le temps de te répondre.

Mon code est très loin d'être optimal je pense, je débute le Javascript depuis 1 semaine et demi pour faire ma formation chez OC.. je dois dire que mon crâne prend quelques claques !

class en plein code métier ? c'est à dire ?

J'ai suivi pas mal de cours et du coup j'ai tendance à me mélanger un peu les pinceaux mais merci pour votre aide !

Merci Matthieu, ton code m'aide à comprendre un peu la logique qu'il faudrait avoir.. bien loin de la mienne pour le coup.
Modifié par Sebastien40 (30 Jan 2020 - 11:31)
limipl a écrit :
Et au lieu de résonner essaie de raisonner.


Effectivement erreur de ma part ! Malheureusement il m'arrive encore de faire des erreurs..
En tout cas, à part ta réflexion, merci de ton aide sur mon post Smiley cligne