Ajax request in ES6 constructor

Asked

Viewed 180 times

0

How I make a request in my constructor Ajax and assign the values of that request to my attributes?

So far it’s like this and it’s not working, I’m returning 2 jsons... in the console.log attributes are empty, that is, the assignment is not being made, the query works normally there in my PHP, I’ve tried it before.

The console shows nothing Using Promisse:

    class pergunta {
      constructor(perguntas, respostas, desafios) {
          return new Promise((perguntas, respostas, desafios) => {
              jQuery.ajax({
                  url: '../php/consulta.php' + location.search,
                  type: "GET",
                  dataType: 'json',
                  success: (pergunta, resposta, desafio) => {
                      this.perguntas = pergunta.pergunta;
                      this.respostas = pergunta.resposta;
                      this.desafios = desafio.descricao;
                  }
              });
          });
      }
  }

  new pergunta().then((perguntas) => {
      console.log(pergunta);
  });

2 answers

2

You got two problems here:

  • #1: The this inside ajax is pointing to jQuery instance, not your constructor because it is not a property of it.

  • #2: Ajax is asynchronous, you can’t do console.log after instantiating the class, as this happens before the replies come from the server.

#1:

Within success: function(pergunta, desafio){ the this aim for jQuery, not what’s around. So if you want to have jQuery this pointing to your class you have 3 alternatives:

  • use the property context and pass on the context reference you want:

Example:

jQuery.ajax({
   url: '../php/consulta.php' + location.search,
   type: "GET",
   dataType: 'json',
   context: this,
   success: function(pergunta, desafio){
       this.perguntas = pergunta.pergunta;
       this.respostas = pergunta.resposta;
       this.desafios = desafio.descricao;

     }
});
  • you can use a sósia/alias, naming self this out of the success jQuery to have a pointer after (the idea that Heber also suggested that).

Example:

const self = this;
jQuery.ajax({
   url: '../php/consulta.php' + location.search,
   type: "GET",
   dataType: 'json',
   success: function(pergunta, desafio){
       self.perguntas = pergunta.pergunta;
       self.respostas = pergunta.resposta;
       self.desafios = desafio.descricao;
     }
});
  • use arrow functions that do not change the execution context:

Example:

jQuery.ajax({
   url: '../php/consulta.php' + location.search,
   type: "GET",
   dataType: 'json',
   success:(pergunta, desafio) => {
       this.perguntas = pergunta.pergunta;
       this.respostas = pergunta.resposta;
       this.desafios = desafio.descricao;
     }
});

#2:

Here you have to use callbacks, Promises or async/await

An example with Promisses could be like this:

class pergunta {
    constructor(id, title) {
        return new Promise((res, rej) => {
            jQuery.ajax({
                url: '../php/consulta.php' + location.search,
                type: "GET",
                dataType: 'json',
                success: (pergunta, desafio) => {
                    this.perguntas = pergunta.pergunta;
                    this.respostas = pergunta.resposta;
                    this.desafios = desafio.descricao;
                }
            });
        });
    }
}

new pergunta().then((perguntas) => {
    console.log(perguntas);
});

Demo with promisse:

class pergunta {
  constructor(id, title) {
    return new Promise((res, rej) => {
      jQuery.ajax({
        url: 'https://jsonplaceholder.typicode.com/posts/1',
        type: "GET",
        dataType: 'json',
        success: ({
          id,
          title
        }) => {
          this.id = id;
          this.title = title;
          res(this);
        }
      });
    });
  }
}
new pergunta().then((perguntas) => {
  console.log(perguntas);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  • I tried to use the Arrow functions and put a function to display, but I do not see anything, from Undefined. I will edit the question, for you see.

  • @Tiagosilveira this new version with exibir has the same problem. You saw mine demo with Promisses? is the idea of .exibir() but respecting the asynchronous nature of ajax. Test this idea.

  • I did it with promisse, but even the console log doesn’t work, I made the appropriate changes giving the get to my api, I tested the pure api and the normal query. I’ll change the question with the edited code.

  • @Tiagosilveira uses my code and creates a jsFiddle with your code for me to see

  • As my code is not online I made using another jsonplaceholder and it didn’t work, look at fiddle: https://jsfiddle.net/L0yb12og/3/ Json: https://jsonplaceholder.typicode.com/posts

  • @Tiagosilveira had some errors: https://jsfiddle.net/L0yb12og/4/

  • In this last example the console does not return anything, nor an Alert runs, another doubt, could explain to me how works the promise so I could work better with it.

  • @Tiagosilvethe last example works well, test again. You can read more about Tweets here: https://answall.com/a/143062/129

  • because nothing is shown to me on the console then? :(

  • @Tiagosilveira tests thus: https://jsfiddle.net/o3uub8tn/

  • I tried again and it was not, I tried to run by Jsbin and ran nothing tbm @Sergio♦

  • @Tiagosilveira have some firewall where you are? or an old browser?

  • @Tiagosilveif any of the answers solved the problem you can mark as accepted. Otherwise it says what is missing to complete!

Show 9 more comments

1

The scope of the Success function of the ajax request is different from the scope of the constructor, try this:

class pergunta {

      constructor(perguntas = [], respostas = [], desafios = [], valor = 100, posicao = 0){

        var _self = this;

        [.. código suprimido ..]

        jQuery.ajax({
           url: '../php/consulta.php' + location.search,
           type: "GET",
           dataType: 'json',
           success: function(data){
               _self.perguntas = data.perguntas;
               _self.respostas = data.respostas;
               _self.desafios = data.desafios;
           }
        });
    }
}
const perguntas = new pergunta();
console.log(perguntas);

Also remember that it is an asynchronous method, so it will only "fill out" the value after the request is finished.

  • I tested, but did not roll, I edited the question.

  • You are not considering that the request is asynchronous, it is another, is using the self alias along with the Arrow Function, see the colleague’s explanation below again, also implement the Promise, this solves your problem.

  • In the Chrome console you can see the properties of the question class instance after the request, I figured the problem was just the scope.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.