skip to Main Content

Variable assigned inside subscribe is empty outside subscribe? why? I know that susbcribe is asynchronous, but, I don’t know how await to render this var… please somebody help me and explain to me. I’m trying to get the value of a subscribe, to then render it in the html, but the value is only retrieved inside the subscribe event and not outside. What can I do to have it in the rest of the component. Thank you.

My service;

import { Injectable } from '@angular/core';
import { Api } from 'src/app/services/api.service';
import { environment as env } from 'src/environments/endpoints';
import { ICode } from '../components/login/login.interfaces';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

private rol$: Subject<any>            

  constructor(
    private api: Api,
  ) {
    this.rol$ = new Subject()
  }

  async verifyCode(data: ICode) {
    const res = await this.api.post(env.auth.login, data)
      .then((res) => {
        if (!res.error) {
          this.isAuthenticated = res.isAuth 
          this.setRol(res.rolUser)           
        }
      })
      .catch((err) => {
        console.log(err)
        return false
      })

    return this.isAuthenticated
  }

  getRolUser$(): Observable<any> {
    return this.rol$.asObservable()
  }

  setRol(rolUser: any) {
    this.rol$.next(rolUser)
  }


}

}
My component;

import { AuthService } from 'src/app/services/auth.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-panel-widgets',
  templateUrl: './panel-widgets.component.html',
  styleUrls: ['./panel-widgets.component.scss']
})
export class PanelWidgetsComponent implements OnInit {

  rolUser$: Observable<any>;

  constructor(
    private _auth : AuthService,
  ) { 
    }

  ngOnInit(){

    this._auth.getRolUser$().subscribe(e => this.rolUser$ = e)       
    
    console.log('Valor del subscribe __ ', this.rolUser$)    
 }

}

Html template

<p class="text">
     <span><b>Usuario : </b><p style="right: 0px;">{{usuario}}</p></span>
     <span><b>Email : </b>{{email}}</span>
     <span><b>Rol : </b>{{ rolUser$ | async }}</span>
 </p>

2

Answers


  1. Chosen as BEST ANSWER

    Finally, this works:

    Service

      import { BehaviorSubject, Observable } from 'rxjs';
    
      isAuthenticated: Boolean = false
      private rol$ = new BehaviorSubject<string>('');  
    
      constructor(
        private api: Api,
      ) {
      }
    

    I use BehaviorSubject instead Subject

    And in my component:

    public rolUser$: Observable<any> | undefined;
    
    ngOnInit() {
        this.rolUser$ = this._auth.getRolUser()
    }
    

    and template html;

    <span><b>Rol : </b>
        {{ rolUser$ | async }}
    </span>
    

  2. Put a console.log inside your subscribe callback and you’ll notice that it’ll be logged after the log outside of the subscription. Those 2 paths don’t run sync.

    You could look up Promises and how to use async/await as well as the Documentation of rxjs

    Also, if you want to use the async pipe, there’s no need to set the value inside the subscription itself

    In you TS do something like this:

    public rolUser$: Observable<any> = this._auth.getRolUser$()
    

    and with that, you have the Observable ready to go into your async pipe, just like you’re already doing

    <span><b>Rol : </b>{{ rolUser$ | async }}</span>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search