Impossible de recuperer JSON (getJSON)

a marqué ce sujet comme résolu.

Bonjour à tous!

J’ai un petit problème

 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
new Vue({
    el: '#ma_div',
    data: {
        books: [],
    },
    methods: {

        searchBooks: function () {
var url = 'https://www.googleapis.com/books/v1/volumes?q=inauthor:' + this.authorName;
                alert("url: " + url);

                $.getJSON(url, function (data) {
                    var galery_data = '';
                    //this.books = data.items;
                    $.each(data.items, function (entryIndex, entry) {
                        galery_data += '<tr>';
                        galery_data += '<td>' + "ok" + '</td>';
                        galery_data += '<td>' + "ok" + '</td>';
                        galery_data += '<td>' + "entry.volumeInfo.authors" + '</td>';
                        galery_data += '<td>' + "entry.volumeInfo.description" + '</td>';
                        galery_data += '</tr>';
                        this.books.push(galery_data);
                    });

                });

voici mon code: l’alert passe bien le problème est que quand je veut récuperer les elements de mon tableau dans mon .html j’ai rien..

Precision : le problème ne vient pas du html, le lien fonctionne, et le texte dans les balises td n’est evidemment pas le bon, c’était pour tester

Merci !

+0 -0

Regarde ce qui se passe dans l’onglet "réseau" de Chrome. La requête est-elle bien partie ? Revenue ? En erreur ?

Tu peux, avec ton navigateur mettre des points d’arrêt dans le code, ici par exemple, à la ligne 13, tu comprendras sans doute mieux ce qui se passe.

+0 -0

Je connais pas Vue donc je sais pas quelle magie se passe derrière, mais j’ai vraiment l’impression que l.22 où tu push dans this.books, ça ne va pas se retrouver dans data.books, la vue ne sera pas mise à jour.

Ce this n’est pas ce que tu penses, je me trompe ?

+1 -0

Merci pour vos réponse , je suis passé par une autre méthode et ai finalement réussi à récuperer les valeurs (avec $http.get(url) ) et j’ai juste fait un this.books = data.items

this represente normalement Vue et a normalement accès à books… ?

+0 -0

Justement, c’est là que tu te plantes. Regarde bien les commentaires que j’ai ajouté à ton code :

 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
new Vue({
  el: '#ma_div',
  data: {
    books: [],
  },
  methods: {
    searchBooks () {
      var url = 'https://www.googleapis.com/books/v1/volumes?q=inauthor:' +
        this.authorName;

      // ici, `this` représente ton objet Vue

      $.getJSON(url, function (data) {
        var galery_data = '';
        // ici, `this` représente le contexte de la function définie l.13
        $.each(data.items, function (entryIndex, entry) {
          galery_data += '<tr>';
          galery_data += '<td>' + "ok" + '</td>';
          galery_data += '<td>' + "ok" + '</td>';
          galery_data += '<td>' + "entry.volumeInfo.authors" + '</td>';
          galery_data += '<td>' + "entry.volumeInfo.description" + '</td>';
          galery_data += '</tr>';
          // ici, `this` représente le contexte de la function définie l.16
          this.books.push(galery_data);
        });
      });

      // ici, `this` représente ton objet Vue

      $.getJSON(url, (data) => {
        var galery_data = '';
        // ici, `this` représente ton objet Vue
        $.each(data.items, (entryIndex, entry) => {
          galery_data += '<tr>';
          galery_data += '<td>' + "ok" + '</td>';
          galery_data += '<td>' + "ok" + '</td>';
          galery_data += '<td>' + "entry.volumeInfo.authors" + '</td>';
          galery_data += '<td>' + "entry.volumeInfo.description" + '</td>';
          galery_data += '</tr>';
          // ici, `this` représente ton objet Vue
          this.books.push(galery_data);
        });
      });
    }

Tant que tu ne comprends pas exactement la différence, tu auras plein d’autres problèmes du même genre que la question qui t’a amenée à créer ce sujet. C’est un cas classique, et tu vas le rencontrer en permanence. :)

+1 -0

Merci bien pour l’explication , ça va me servir ! ;)

D’ailleurs maintenant j’ai un autre problème:

 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
new Vue({
    el: '#book_manage',
    /*created: function(){  // ici ça marche mais quand je veut remplir mon tableau lors du click 
                               tableau = vide
        this.searchBooks();
    },*/
    data: {
        personnes: [
            {
                nom: "Durand",
                prenom: "Jacques"
            },
            {
                nom: "Dupont",
                prenom: "Albert"
            },
            {
                nom: "Martin",
                prenom: "Denis"
            },
        ],
        authorName: '',
        books: [],
        columns: ["Title", "Année", "Descriptif", "Illustration"],
    },
    methods: {

        searchBooks() {

                this.$http.get('https://www.googleapis.com/books/v1/volumes?q=inauthor:musso'  , {
                    method: 'POST',
                    dataType: 'json'
                }).then(function(response){
                    this.books = response.data.items;
                }).catch(function(error){
                    alert("ERROR");
                });

      //  }

    }
});
});

Mon HTML:

1
2
3
4
5
6
7
<template v-for="book in books">
                        <tr>
                            <td><img id="imageBook" v-bind:src="book.volumeInfo.imageLinks.thumbnail" alt=""></td>
                            <td>{{ book.montruc }}</td>
                            <td>{{ book.monautretruc }}</td>
                        </tr>
                    </template>

Rmq : mon boutton : ```html <input type="submit" id="butto" value="Search" v-on:click="searchBooks">

```

Le boutton marche evidemment ,le problème c’est que j’ai l’impression que du coup v-for ne marche que pour le chargement de page je me trompe?? Il y’aurais pas un moyen d’afficher le tableau à chaque click en gardant le v-for ou bien faut il que je passe mon code avec un .append(monCode) ou autre?

Je suis sérieux. Si tu comprends pas à quoi fait référence this, tu vas continuer à faire la même erreur encore et encore, à avoir le même problème encore et encore.

Tu as fait l’erreur 1x, je t’ai dit que si tu apprenais pas ça correctement tu re-ferais la même erreur très souvent, tu as refais l’erreur immédiatement après. Tu peux me croire et apprendre un point central et basique de JavaScript et ne plus jamais faire cette erreur, ou continuer à chercher le problème là où il n’est pas. Tu choisis.

Si tu décides que tu veux comprendre, lis ce code et tente de deviner ce qu’il affiche :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function A () {
  this.val = 'x'
  console.log('1', this.val)

  ;(function () {
    console.log('2', this.val)
    this.val = 'y'
    console.log('3', this.val)
  })()

  console.log('4', this.val)

  ;(() => {
    this.val = 'z'
  })()
  console.log('5', this.val)
}

new A()

Ensuite exécute-le. Comme t’avais pas la bonne réponse sans l’exécuter, c’est le moment idéal de comprendre pourquoi et comment.

+1 -0

Hello,

Une fonction dans l’objet methods dans VueJS est une action provoquée par l’utilisateur par un évènement (comme un click par exemple).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<div id="book_manage">
  <button @click="searchBooks">Rechercher</button>

  <table v-for="book in books">
    <tr>
      <td><img id="imageBook" v-bind:src="book.volumeInfo.imageLinks.thumbnail" alt="" /></td>
      <td>{{ book.volumeInfo.title }}</td>
    </tr>
  </table>
</div>

Ce code fonctionne bien sur JsFiddle

En revanche, si tu veux consulter l’API au démarrage de la page, utilise la fonction mounted.

1
2
3
4
5
6
7
8
mounted: function() {
    this.$http.get('https://www.googleapis.com/books/v1/volumes?q=inauthor:musso')
    .then(function(response) {
        this.books = response.data.items;
    }).catch(function(error) {
        alert("ERROR");
    });
}

Egalement disponible sur JsFiddle.

+0 -0

Ok, donc le client http fait de la magie en bindant l’instance de Vue sur tous les callbacks. :/

Ouais confirmé par la doc : https://github.com/pagekit/vue-resource/blob/develop/docs/http.md#usage

the Vue instance will be automatically bound to this in all function callbacks

x(

+0 -0

Ca fait partie des défauts de Vue, oui.

Les mêmes que ceux de Spring en fait, y’a de la magie cachée, qui fait que tu passes plus de temps à apprendre des conventions qu’un langage ou un paradigme, gain de productivité au début du chemin (et peut-être à la fin), mais le chemin en lui-même est bof bof.

+0 -0

Vaut-il mieux binder l’instance this avec .bind(this) ou utiliser l’astuce de var that = this; ?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function A () {
  this.val = 'x'
  console.log('1', this.val, "chang")

  ;(function () {
    console.log('2', this.val, "verif")
    this.val = 'y'
    console.log('3', this.val, "chang")
  }).bind(this)()

  console.log('4', this.val, "verif")

  ;(() => {
    this.val = 'z'
  }).bind(this)()
  console.log('5', this.val, "chang")
}

new A()
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte