0

I'm trying to make an app using angular and node, when I make a new register I need to show a message, in this case a snackbar because I'm using materialize for angular.

I've declared a variable on my class and I give it value after I click submit, but when it calls the service and received its response, it doesn't set the value, the console keeps saying that the variable it's undefined. Here's the full code of that component.

import { Component, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { Clase } from 'src/app/models/clase';
import { ClaseService } from 'src/app/services/clase.service';
import { Catalogo } from 'src/app/models/catalogo';
import { MatSnackBar } from '@angular/material';

@Component({
  selector: 'app-crear-cuenta',
  templateUrl: './crear-cuenta.component.html',
  styleUrls: ['./crear-cuenta.component.css'],
  providers: [ClaseService]
})

export class CreateCuentaComponent implements OnInit {
  public title = 'Nueva Cuenta'
  public register_catalogo: Catalogo;
  public register_clase: Clase;
  public alertMessage: string;

  constructor(
    public snackBar: MatSnackBar,
    private _claseService: ClaseService,
  ){
    this.register_catalogo = new Catalogo('', '', null);
    this.register_clase = new Clase('', '' ,'' , null);
  }

  ngOnInit(){
    //console.log(this.alertMessage)
  }

  public onSubmit() {
    let option = this.register_catalogo.codigo.length;
    switch(option) {
      case 1:
        this.CreateClase();
        //this.alertMessage = 'Hola Mundo'
        console.log(this.alertMessage)
        //Pop-up de alerta en la parte inferior
        this.openSnackBar(this.alertMessage, 'Cerrar')
      break;
    }
  }

  CreateClase() {
    //Enviar valores al modelo Clase
    this.register_clase.codigo = this.register_catalogo.codigo;
    this.register_clase.clase =  this.register_catalogo.cuenta;
    this.register_clase.saldo = this.register_catalogo.saldo;
    this._claseService.createClase(this.register_clase).subscribe(
      response => {
        //Crear la nueva clase
        let clase = response.claseStored;
        this.register_clase = clase;

        if(!clase._id) {
          this.alertMessage = 'Error al registrar la clase';
        } else {
          this.alertMessage = 'La clase se ha registrado con éxito';
          this.register_catalogo = new Catalogo('', '', null);
          this.register_clase = new Clase('', '' ,'' , null);   
        }
      },
      error => {
        var alertMessage = <any>error;
        if(alertMessage != null){
          var body = JSON.parse(error.body);
          this.alertMessage = body.message;
          this.register_catalogo = new Catalogo('', '', null);
          this.register_clase = new Clase('', '' ,'' , null);  
        }
      }
    )
  }

  openSnackBar(message: string, action: string) {
    this.snackBar.open(message, action, {
      duration: 2000,
    });
  }
}

In order to have a result from calling my service, I expect to give a string value to alertMessage and show it on the snackbar.

2 Answers2

1

For this.openSnackBar(this.alertMessage, 'Cerrar') to display the message it should be called inside CreateClase() after you had set the alterMessage. Since the service is async, it will take time to fetch the data. So if you try to display the message before the callback, it will be displaying undefined or wrong value (wrong value in case if value has already been set from previous execution)

Updating your code by following the steps

1.Remove this.openSnackBar(this.alertMessage, 'Cerrar') from the case of switch

switch(option) {
      case 1:
        this.CreateClase();
        //other code here 
        //this.openSnackBar(this.alertMessage, 'Cerrar') <-REMOVE this from here as it will always return undefined
      break;
    }

2.Add this.openSnackBar(this.alertMessage, 'Cerrar') after setting value to this.alertMessage

CreateClase() {
//other codes
this._claseService.createClase(this.register_clase).subscribe(
      response => {
        //Crear la nueva clase
        let clase = response.claseStored;
        this.register_clase = clase;

        if(!clase._id) {
          this.alertMessage = 'Error al registrar la clase';
        } else {
          this.alertMessage = 'La clase se ha registrado con éxito';
          //other code here 
        }

        this.openSnackBar(this.alertMessage, 'Cerrar') //<-call the function after getting the value 

      },
      error => {
        var alertMessage = <any>error;
        if(alertMessage != null){
          var body = JSON.parse(error.body);
          this.alertMessage = body.message;

          this.openSnackBar(this.alertMessage, 'Cerrar') //<-call the function after getting the value
          //other code here  
        }
      }
    )
}
Seba Cherian
  • 1,755
  • 6
  • 18
  • Thank you! This actually worked but it doesn't print the error message. Am I missing something else? – Manuel Alfaro Mar 30 '19 at 02:05
  • Can you check by console.log(this.alertMessage) just before last this.openSnackBar() inside error block to ensure you are getting the value? – Seba Cherian Mar 30 '19 at 04:25
1

Your problem is using asynchronous call. You can use Callback, promises or generators to fix this issue.

  public onSubmit() {
  let option = this.register_catalogo.codigo.length;
  switch(option) {
    case 1:
      this.CreateClase(function(){
          //this.alertMessage = 'Hola Mundo'
          console.log(this.alertMessage)
          //Pop-up de alerta en la parte inferior
          this.openSnackBar(this.alertMessage, 'Cerrar')
       });
    break;
  }
}
CreateClase(cb: Function) {
//Enviar valores al modelo Clase
this.register_clase.codigo = this.register_catalogo.codigo;
this.register_clase.clase =  this.register_catalogo.cuenta;
this.register_clase.saldo = this.register_catalogo.saldo;
this._claseService.createClase(this.register_clase).subscribe(
  response => {
    //Crear la nueva clase
    let clase = response.claseStored;
    this.register_clase = clase;

    if(!clase._id) {
      this.alertMessage = 'Error al registrar la clase';
    } else {
      this.alertMessage = 'La clase se ha registrado con éxito';
      this.register_catalogo = new Catalogo('', '', null);
      this.register_clase = new Clase('', '' ,'' , null);   
    }
    cb();
  },
  error => {
    var alertMessage = <any>error;
    if(alertMessage != null){
      var body = JSON.parse(error.body);
      this.alertMessage = body.message;
      this.register_catalogo = new Catalogo('', '', null);
      this.register_clase = new Clase('', '' ,'' , null);
      cb();
    }
  }
)}

Here is a simple solution using callback.

ilyas shabi
  • 194
  • 1
  • 7