IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Utiliser variable comme paramètre d'un élément dans Map / forEach


Sujet :

JavaScript

  1. #1
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 126
    Par défaut Utiliser variable comme paramètre d'un élément dans Map / forEach
    Bonjour à tous,

    Dans une classe dédiée utilisant fetch, j'ai créé un tableau de paramètres appelé dataKeys[] qui permet de renseigner les clés que l'on veut utiliser pour filtrer du data retourné en JSON.

    Dans le map ci-dessous je peux spécifier le premier paramètre / clé du tableau grâce à l'expression 'data[this.dataKeys[0]]', cela me retourne bien un résultat correct, cependant, quand j'applique la même écriture sur l'élément (el) je reçois un "undefined"... J'ai essayé tous les styles d'écritures possibles pour qu'il soit possible de mettre en variable '[this.dataKeys[1]]' par rapport à l'élément (el), rien n'y fait... Il s'agît bien d'un object pourtant de même que 'data', pourquoi cette écriture n'est t'elle pas acceptée dans le corps du map ?. Je précise que data contient bien le json retourné et que si je rentre manuellement les clés spécifiées dans dataKeys[1] cela marche parfaitement !

    Merci d'avance pour vos suggestions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            data[this.dataKeys[0]].map((el) => {
                    let recherche = el[this.dataKeys[1]];
                    console.log("résultat =", recherche);  
                  });

  2. #2
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 496
    Par défaut
    Bonjour,

    Pour répondre à vos questions, il faudrait d'abord voir la structure de l'objet data et les valeurs du tableau this.dataKeys.

    Il me semble aussi que ce n'est pas map qu'il vous faut pour filtrer les propriétés imbriqués d'un objet...

  3. #3
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 126
    Par défaut
    Bonjour et merci Toufik d'avoir répondu,

    Il s'agissait en fait que la clé comprenait un point au milieu ce qui n'est pas accepté, j'avais mis dans le tableau ["properties.label"] or, il faut apparemment décomposer chaque clé séparée par une virgule en écrivant ["properties","label"].

    J'ai créé deux tableaux dans ma classe : "dataKeys[] et elementKeys[]" qui servent à spécifier les possibles clés à renseigner après (data) et (el) dans le forEach / Map traitant le Json retourné.

    Ce que je voudrais maintenant c'est pouvoir concaténer les différentes clés fournies par l'utilisateur au bon endroit en faisant une boucle sur les deux tableaux mis en variables, si j'écris par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[this.dataKeys[0]].map((el) => { console.log(el[this.elementKeys[0]][this.elementKeys[1]]);});
    Cela marche parfaitement dans la classe mais je ne sais pas comment créer la boucle qui permettrait de coller les deux tableaux suivants l'objet (data) ou (el) par code / boucle après "el" ou "data" comme l'exemple ci-dessus, je sais le faire en tant que string mais il faut que cela soit reconnu comme objet/tableau ici ... Une idée ?
    Cela permettant de créer une arborescence de clés tant dans data que dans l'élément du forEach / Map...

    Par exemple dans le cas actuel je dois accèder à data.features et ensuite à el.properties.label ce qui correspond aux clés de l' API adresse géo .fr que je renseigne coté fonction en renseignant les deux tableaux dataKeys et elementKeys...

    Ma classe est instanciée de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let resultat = new Search(
      "https://api-adresse.data.gouv.fr/search/?q=",
      "GET",
      "contacts_adresse",
      "recherche-adresse",
      ["features"],
      ["properties", "label"],
      true
    ).init();
    console.log("Résultat = ", resultat);
    Search.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    export class Search {
      /**
       * @param { String } url Spécifie l'url requise (controller)
       * @param {string} method Spécifie la méthode GET ou POST
       * @param { String } searchInputId Spécifie l'id du champ de recherche ciblé
       * @param { String } resultsFieldId Spécifie l'id du champ d'affichage des résultats
       * @param {boolean} createList (false par défaut) Spécifie si le résultat doit être présenté en tant que liste dans le champ de résultats
       * @param {Array} dataKeys Spécifie les clés en première position pour (data) dans le Json reçu
       * @param {Array} elementKeys Spécifie les clés à rechercher pour chaque élément dans le forEach ou map (el)
       */
      constructor(
        url,
        method,
        searchInputId,
        resultsFieldId,
        dataKeys = [],
        elementKeys = [],
        createList = false
      ) {
        this.url = url;
        this.method = method;
        this.searchInputId = searchInputId;
        this.resultsFieldId = resultsFieldId;
        this.resultsFieldId = document.querySelector(`#${this.resultsFieldId}`);
        this.searchInputId = document.querySelector(`#${this.searchInputId}`);
        this.createList = createList;
        this.dataKeys = dataKeys;
        this.elementKeys = elementKeys;
      }
      init() {
        this.fetchData();
      }
      fetchData() {
        let response = "";
        let timeout = null;
        const formData = new FormData();
     
        this.searchInputId.addEventListener("keyup", (e) => {
          e.preventDefault();
          let recherche = this.searchInputId.value;
     
          if (recherche.length > 0) {
            if (timeout !== null) {
              clearTimeout(timeout);
            }
            timeout = setTimeout(() => {
              rechercher(formData, recherche);
            }, 1000);
          }
        });
        const rechercher = async (formData, recherche) => {
          try {
            if (this.method === "POST") {
              formData.append("recherche", recherche);
              response = await fetch(this.url, {
                method: this.method,
                headers: { Accept: "application/json" },
                body: formData,
              });
            } else {
              response = await fetch(`${this.url}${recherche}`, {
                method: this.method,
                headers: { Accept: "application/json" },
              });
            }
     
            if (response.ok) {
              let data = await response.json();
     
              this.resultsFieldId.innerHTML = "";
              if (data || data.content !== "") {
                let dataKeyStr = "";
                let elementKeyStr = "";
     
                //Boucle sur les possibles clés concernant l'objet (data)
                for (let i = 0; i < this.dataKeys.length; i++) {
                  dataKeyStr += `${this.dataKeys[i]}`;
                }
     
                //Boucle sur les possibles clés concernant l'élément (el)
                for (let i = 0; i < this.elementKeys.length; i++) {
                  elementKeyStr += `${this.elementKeys[i]}`;
                }
     
                console.log("data = ", data[this.dataKeys[0]]);
     
                data[this.dataKeys[0]].map((el) => {
                  console.log(el[this.elementKeys[0]][this.elementKeys[1]]);             
                });
     
                if (this.createList) {
                  //Crée une liste de valeurs pour autocomplete
                  // const ul = document.createElement("ul");
                  //   let li = document.createElement("li");
                  //   li.textContent = el.properties.label;
                  //   ul.append(li);
                  // this.resultsFieldId.append(ul);
                } else {
                  //Affiche simplement le résultat dans le champ
                  this.resultsFieldId.insertAdjacentHTML(
                    "afterbegin",
                    data.content
                  );
                }
              } else {
                this.resultsFieldId.innerHTML = `<p class="alert">Aucun résultat trouvé avec ces termes : "${this.searchInputId.value}"</p>`;
              }
            }
          } catch (error) {
            console.log(error);
          }
        };
      }
    }

  4. #4
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 496
    Par défaut
    Bonjour,

    Il faut qu'on analyse un peu les choses avant de commencer le changement de code, parce que si je lance la requête https://api-adresse.data.gouv.fr/search/?q=aaa vers l'api avec le paramètre ?q=aaa, j'obtiens la réponse suivante
    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    {
        "type": "FeatureCollection",
        "version": "draft",
        "features": [
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        7.169277,
                        48.04387
                    ]
                },
                "properties": {
                    "label": "Haag 68140 Gunsbach",
                    "score": 0.16531272727272728,
                    "id": "68117_89zffn",
                    "banId": "c6cf3aa1-fb70-4ca7-af54-8fa2444b9db6",
                    "name": "Haag",
                    "postcode": "68140",
                    "citycode": "68117",
                    "x": 1010541.22,
                    "y": 6779698.99,
                    "city": "Gunsbach",
                    "context": "68, Haut-Rhin, Grand Est",
                    "type": "street",
                    "importance": 0.31844,
                    "street": "Haag"
                }
            },
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        2.280121,
                        48.910009
                    ]
                },
                "properties": {
                    "label": "Allée Haag 92600 Asnières-sur-Seine",
                    "score": 0.12733272727272726,
                    "id": "92004_3433",
                    "banId": "d5734f7d-86a2-47a7-88df-ef4ef8d3e730",
                    "name": "Allée Haag",
                    "postcode": "92600",
                    "citycode": "92004",
                    "x": 647234.66,
                    "y": 6868019.77,
                    "city": "Asnières-sur-Seine",
                    "context": "92, Hauts-de-Seine, Île-de-France",
                    "type": "street",
                    "importance": 0.65066,
                    "street": "Allée Haag"
                }
            },
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        6.900886,
                        49.186191
                    ]
                },
                "properties": {
                    "label": "Ruelle Haas 57600 Forbach",
                    "score": 0.11052524475524475,
                    "id": "57227_0555",
                    "banId": "3aa676ac-504e-4086-9a36-908ec01f8f78",
                    "name": "Ruelle Haas",
                    "postcode": "57600",
                    "citycode": "57227",
                    "x": 984296.13,
                    "y": 6905518.61,
                    "city": "Forbach",
                    "context": "57, Moselle, Grand Est",
                    "type": "street",
                    "importance": 0.52347,
                    "street": "Ruelle Haas"
                }
            }
        ],
        "attribution": "BAN",
        "licence": "ETALAB-2.0",
        "query": "aaaaa",
        "limit": 5
    }

    En modifiant la valeur du paramètre q de 'aaa' en 'ccc' j'obtiens
    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    {
        "type": "FeatureCollection",
        "version": "draft",
        "features": [
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        8.808625,
                        41.895985
                    ]
                },
                "properties": {
                    "label": "CC U paese 20128 Grosseto-Prugna",
                    "score": 0.11687181818181817,
                    "type": "locality",
                    "importance": 0.38559,
                    "id": "2a130_cjcglw",
                    "banId": "a3c4dc5b-d54b-4b97-ada2-f4246e410400",
                    "name": "CC U paese",
                    "postcode": "20128",
                    "citycode": "2A130",
                    "x": 1182663.57,
                    "y": 6106121.37,
                    "city": "Grosseto-Prugna",
                    "context": "2A, Corse-du-Sud, Corse",
                    "locality": "CC U paese"
                }
            },
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        1.7547,
                        45.260129
                    ]
                },
                "properties": {
                    "label": "Parking CCS 19000 Tulle",
                    "score": 0.11593016528925619,
                    "type": "locality",
                    "importance": 0.45705,
                    "id": "19272_v1779z",
                    "banId": "e32018c5-ae48-4ca9-a66e-43bf9a7f7a7a",
                    "name": "Parking CCS",
                    "postcode": "19000",
                    "citycode": "19272",
                    "x": 602330.81,
                    "y": 6463079.41,
                    "city": "Tulle",
                    "context": "19, Corrèze, Nouvelle-Aquitaine",
                    "locality": "Parking CCS"
                }
            }
        ],
        "attribution": "BAN",
        "licence": "ETALAB-2.0",
        "query": "ccc",
        "limit": 5
    }

    Ceci dit que l'api retourne seulement les objets features ayant au moins une propriété contenant les 2 premières lettres du paramètre q ('aa' ou 'cc' pour ce cas), et donc vous savez déjà que vous recevez toujours un tableau d'objets nommé features et que chaque élément de ce tableau contient forcément les sous propriétés type,geometry et properties.

    La question est : à quoi sert-elle la propriété dataKeys = [] dans le constructeur de la class Search qui représente le paramètre ["features"] dans l'initialisation si l'utilisateur n'a pas le choix et qu'il va forcément parcourir data.features? , car ce n'est pas possible d'écrire par exemple ["peuImport"] et le passer en tant que valeur de la propriété dataKeys non?

    Corrigez moi si je me trompes...

    La même chose pour le paramètre elementKeys = [] représenté par ["properties", "label"], sauf que cette fois l'utilisateur a le choix de choisir les propriétés qu'ils veut récupérer, puisqu'ils y a plusieurs possibilités feature.type, feature.geometry, feature.geometry.type, feature.geometry.coordinates, feature.properties, feature.properties.(les autres items), mais si vous insistez, on va essayer de trouver une solution.

    J'ai compris que vous essayez d'appliquer un autocomplete à la zone de texte de recherche, et que vous souhaitez afficher une liste en fonction des données reçues, et aussi que la classe Search retourne un objet qu'on peut exploiter dans les scripts JS, c'est ça ?

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 126
    Par défaut
    Merci beaucoup Toufik d'avoir répondu

    En fait par utilisateur je voulais dire développeur, celui qui connaitrait d'avance les clés à utiliser et qui les renseignerait dans les deux tableaux possibles ...

    Malgré toutes mes expérimentations, il paraît difficile par code de produire des chaînes comme préfixes du fetch du genre :

    data +[clé1][clé2] ... etc ou bien aucune clé...

    J'ai essayé en utilisant des chaînes avec backtits mais ce n'est pas correctement interprété dans le fetch, bloquant tout le code car ce n'est pas reconnu comme correct...

    Il doit y avoir une solution mais je ne la connais pas encore...

Discussions similaires

  1. utiliser variable comme chemin SSIS
    Par vanessa75 dans le forum SSIS
    Réponses: 1
    Dernier message: 29/03/2017, 11h24
  2. Réponses: 12
    Dernier message: 20/11/2015, 12h52
  3. Utiliser une variable comme nom de table Access dans une requête SQL
    Par stsym dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 09/10/2011, 17h11
  4. Utiliser typename comme nom de variable
    Par Harzoglups dans le forum C++
    Réponses: 5
    Dernier message: 04/01/2006, 14h44
  5. [curseurs] utiliser une variable comme nom de champ
    Par Christian31 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/09/2005, 14h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo