Problems when receiving list of Storage values in a variable (Ionic)

Asked

Viewed 56 times

0

Tenho os dados armazenados assim no Sotorage

Código que deveria atribuir os valores do Storage a variável prods

I have the data stored in Storage as it is in the first image and in the second image the code that should assign the Storage values to the Prods variable. This code is in a method that I will call at the click of a button. But after I call the method and print the value of the variable Prods, it is as Undefined. :(


Button code, where the method is called (add or update) depending on the situation.

    <ion-button expand="block" icon-start (click)='add_or_update()'>

      <ng-template *ngIf="product.id;then btn_update; else btn_add"></ng-template>

      <ng-template #btn_update>
        <ion-icon name="create"></ion-icon>
        Atualizar
      </ng-template>

      <ng-template #btn_add>
        <ion-icon name="add"></ion-icon>
        Adicionar
      </ng-template>

    </ion-button>

Method that checks which action to perform (add or update)

add_or_update() {
  this.product.id ? this.update() : this.add();
}

Method add that will call the method that contains the problem code

add() {
    this.loadingService.present();
    this.product.profile = this.auth.user.profile_id;

    this.checkProductTagStorage(); // #### AQUI ####

    this.productService.add(this.product).subscribe(
      data => {
        this.loadingService.dismiss();
        this.toastService.success('Animal cadastrado com sucesso!');
        this.products.unshift(this.product);
        this.clear();
      },
      error => {
        this.loadingService.dismiss();
        this.toastService.error('Erro ao cadastrar produto!');
      }
    );
  }

Method in which the problem occurs

  checkProductTagStorage() {
    this.prods = [];

    this.storage.get('coovita-prods-list-type-1').then((data) => {
      this.prods = data;
      console.log(this.prods); // Imprimindo a variavel está com os dados corretos
    });

    console.log(this.prods); // Imprimindo aqui a variavel está vazia []
  }
  • Would it be possible to provide more details to reproduce the problem? Maybe setting an example in stackblitz will help other people better understand the problem.

  • I get a list of products from an API and then store in the Storage. Then I want to pass this data from the Storage to a variable. The strange thing is that inside this get the image if I have the Prods variable printed will print the values correctly. However, even after calling the method that makes this request, if I have the variable printed it is as Undefined. What would be really interesting I show to help?

  • It would be nice to post the snippet of your template where the variable prods is used and the button activating the function get. From what I’ve seen so far it’s all right! after calling the get the variable prods is completed and may be used in other parts of the code.

  • I don’t use the variable in the template, I want this data just to check if there is already a registered tag with the same value. I edited the description and added the methods. I don’t understand why the data is being correctly received only within the get function. :(

  • Now it’s clearer. I’ll leave the answer with the details. I hope it helps :)

1 answer

0


When calling the function add() the browser will interpret line by line of this method. When he arrives at the this.checkProductTagStorage() he calls that function and he’s on to the next one line this.productService.add(this.product).subscribe(....

Your problem is precisely there because within the method checkProductTagStorage the stretch this.storage.get is executed asynchronously. Soon, this.prods is updated after the method add() has already been executed.

An example of what is happening with your code:

let prods = null;

function add1() {
  checkProductTagStorage1();
  console.log(prods);
}

function checkProductTagStorage1() {
  // Atualiza o prods depois de 200ms
  setTimeout(() => { prods = 1; }, 200);
}

add1();
setTimeout(() => { console.log(prods); }, 200);

One of the ways to solve is to use a Promise with the async\await:

    let prods = null;

    async function add1() {
      await checkProductTagStorage1();
      console.log(prods);
    }

    function checkProductTagStorage1() {
      return new Promise(resolve => {
        // Atualiza o prods depois de 200ms
        setTimeout(() => {
          prods = 1;
          resolve();
        }, 200);      
      });
    }

    add1();
    setTimeout(() => { console.log(prods); }, 200);

In your code it would be something like:

async add() {
    this.loadingService.present();
    this.product.profile = this.auth.user.profile_id;

    await this.checkProductTagStorage(); // #### AQUI ####

    this.productService.add(this.product).subscribe(
        data => {
            this.loadingService.dismiss();
            this.toastService.success('Animal cadastrado com sucesso!');
            this.products.unshift(this.product);
            this.clear();
        },
        error => {
            this.loadingService.dismiss();
            this.toastService.error('Erro ao cadastrar produto!');
        }
    );
}

checkProductTagStorage() {
    return new Promise(resolve => {
        this.prods = [];

        this.storage.get('coovita-prods-list-type-1').then((data) => {
            this.prods = data;
            console.log(this.prods); // Imprimindo a variavel está com os dados corretos

            resolve(); // Indica que a promise foi resolvida
        });

        console.log(this.prods); // Imprimindo aqui a variavel está vazia []
    });
}
  • Perfect. I had already seen the loading of the data in the variable being done in the correct way when I ran the Storage. in the method ionViewWillEnter. I was even looking for an explanation for this. Your explanation solved everything here :) Thank you very much !!

Browser other questions tagged

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