Paco Pinazo Guna
Paco Pinazo Guna

Reputation: 117

I want to create a localstorage inside a .subscribe but it creates the localstorage after all the functions

I am trying to check in a form is the user exists in a MySQL Database with angular. I am creating a localstorage item inside a .subscribe so if the user exists it creates a localstorage like this:

localStorage.setItem("exist","true"); 

but if it doesn't exist makes this:

localStorage.setItem("exist","false");

After the function I check if it is true or false, but it is null, because .subscribe makes it after all the functions. So if I check a 2nd time it makes the localstorage item correctly.

this.userService.getAutor(id)
  .subscribe(
    (data) => { // Successins
      localStorage.setItem("exist","true");
    },
    (error) => { // error
      localStorage.setItem("exist","false");
    }
  );
}

This is where I am calling the function

  this.usuarioExiste(this.dniAutor);

      if(localStorage.getItem('existe') == 'false'){
        var expReg = /^(\d{8})([A-Z])$/;

        if(expReg.test(this.dniAutor)){

          this.userService.crearAutor(JSONform)
          .subscribe(

            (data) => { // Success
              console.log("¡Bien HECHO!");
            }
          );
          alert("Autor añadido correctamente");
        }
else{
  alert("Dni mal introducido")
}

Upvotes: 0

Views: 510

Answers (3)

Paco Pinazo Guna
Paco Pinazo Guna

Reputation: 117

It finally worked!

I used the suggestion of 0leg and it worked!

this.userService.getAutor(id).subscribe(data => {
      if (data) {
        localStorage.setItem('existe', 'true');
      } else {
        localStorage.setItem('existe', 'false');
      }
    });

Many thanks to all!

Have a nice day!

Upvotes: 0

ionut-t
ionut-t

Reputation: 1177

As Kurt mentioned, my answer needs an explanation.

So I'll do my best below:

You have to check first if the data is available when you are in the subscribe method due to the asynchronous nature of the call. And only then you access the local storage as you intend.

Note: You can also use the filter operator like so filter(data => data) to skip the if condition but only if you're not interested to access the local storage if the data doesn't exist.

 this.userService.getAutor(id).subscribe(data => {
      if (data) {
        localStorage.setItem('existe', 'true');
      } else {
        localStorage.setItem('existe', 'false');
      }
    });

Upvotes: 0

0leg
0leg

Reputation: 14154

After the function I check if it is true or false, but it is null

Wrong way

this.userService.getAutor(id)
  .subscribe(
    (data) => { // Successins
      localStorage.setItem('existe',"true"); // <-- called after functionCheckIfTrueOrFalse, NO DATA in storage yet
    },
    (error) => { // error
      localStorage.setItem('existe',"false"); // <-- called after functionCheckIfTrueOrFalse, NO DATA in storage yet
    }
  );
}
functionCheckIfTrueOrFalse() // <- is called before any localStorage.setItem()

Correct way

this.userService.getAutor(id)
  .subscribe(
    (data) => { // Successins
      localStorage.setItem('existe',"true");
      functionCheckIfTrueOrFalse() // <- localStorage HAS the data
    },
    (error) => { // error
      localStorage.setItem('existe',"false");
      functionCheckIfTrueOrFalse() // <- localStorage HAS the data
    }
  );
}

Knowledge

If you want to spend time and understand how it works under the hood, you can check this article.

In nutshell JavaScript handles async treads differently:

enter image description here

You get null because you are reading data from the sync Queue before you get data from the Async tread.

Upvotes: 1

Related Questions