Firebase object always returning Undefined out of subscribe

Asked

Viewed 156 times

0

I’m trying to do something simple. It happens that I need to obtain the quantity of stock of that item, at that given moment to then make the return and the feed of the stock correctly. I’ve built the entire algorithm, but I’m having a hard time sending an update to my firebase product node.

1º Whenever I try to show the value of the object outside of subscribe, it returns Undefined.

2º I can’t work with any of his property outside of the subscribe, so I can’t make the sum of the return and stock quantities.

3º It only works if I update inside the subscribe, but it returns me an infinite loop, enough to lock my browser, now I do not know how to proceed in this case.

My code is super simple:

  devolverItem(item: any){
   let pathItens = `/itens/`;
   this.itensFirebase = this.db.list(pathItens, {
     query: {
     orderByChild: 'key',
     equalTo: item.key
   }
  });

  this.itensFirebase.subscribe( data => {
     this.itemEstoqueSemGrade = data;
  })

  //Aqui ele me retorna sempre o undefined
  console.log(this.itemEstoqueSemGrade);
 }

This is an example of how "it works", but with the loop:

  devolverItem(item: any){
   let pathItens = `/itens/`;
   this.itensFirebase = this.db.list(pathItens, {
     query: {
       orderByChild: 'key',
       equalTo: item.key
     }
   });

   this.itensFirebase.subscribe( data => {
     this.itemEstoqueSemGrade = data;
     this.quantidadeItemAtualizarEstoqueTotal = 
     this.itemEstoqueSemGrade[0].quantidade + item.quantidadeDevolver;
     this.db.object(`/itens/${item.key}/`).update({
        quantidade: this.quantidadeItemAtualizarEstoqueTotal
     })
   })

 }

This second option in my view does not make any sense, I understand that I would have to do it out of there, but if I try to work with the data of my itemEstoqueSemGrade out of there, it always returns me Undefined, so I can not perform any operation.

Any help will be welcome..

  • Diego, I improved the code by putting an example with your code, only after I had published I saw that you were using Angularfire and improved the response.

1 answer

1

Good night buddy,

Let’s go to the technical explanation first, this Code of yours is Asynchronous, and some things are happening in a different order than what is written, you are making use of Observables in this case through the Subscribe method, ie your first prolema is that the console.log() is running before the subscribe content.

When you run the Subscribe method, you pass a Function as parameter, this Function is being subscribed to an Observable, and not running immediately, the Observable queue is who will run this code 1 or more times.

Your second problem is this "more times" you said earlier, the command. update() updates the data in firebase, and as this connection is Altime, the Function you passed in the subscribe wheel again, and again, and enters the infinite loop you identified.

To solve your problem you need to use firebase’s Once methods, which are not connected in real time, but which returns the list once and does not keep track of changes, so you can update.

look at an example with your code (untested)

 devolverItem(item: any){
   let pathItens = `/itens/`;
   this.itensFirebase = this.db.database.ref(pathItens)
   .orderByKey()
   .equalTo(item.key);

   this.itensFirebase.once('value', data => {
      this.itemEstoqueSemGrade = data;
   });

  //Aqui ele me retorna sempre o undefined
  // aqui sempre vai retorna Undefined porque roda antes do observable
  console.log(this.itemEstoqueSemGrade);
 }

Even in this example you will notice a "chaining" of code, similar to what you put in your second code, and this is normal, as I said, the Function that is being subscribed by the Subscribe method will be executed asynchronously, since there is a time of waiting for the data, the same happens for this Function that I’m going through inside the . then(), in this case, other than subscribe, which maintains a real-time connection (its update triggered the method again), the . then() will run only once when the list is returned, in technical terms when Promisse is Resolved.

Follow the link to the Realtime Database doc, if you are using the Firebase Firestore you will find the documentation on the same site, procumer the method. Once

https://firebase.google.com/docs/database/web/read-and-write?hl=pt-br

Browser other questions tagged

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