Managing asynchronous data using rxjs

I created a loginComponent that is responsible for receiving an email and password from the user, then making an HTTP request to retrieve the user data. My goal is to utilize this user data in other components through a service.

Here is the login component:

  onRecievingResults(value:loginInterface){
    this.authService.saveData(value);
  }

  onLog(){
    this.onRecievingResults(this.loginUser)
    this.router.navigateByUrl('/stats/list')
  }

The service implementation:

  public currentUser:User | null = null;

private dataUserSource = new BehaviorSubject<User | null>(this.currentUser);
  dataEmitter = this.dataUserSource.asObservable();

  public saveData(value:loginInterface){
    this.loginUser(value).subscribe()
    this.dataUserSource.next(this.currentUser);
  }

  public loginUser(loginInterface: loginInterface | null){
    const url = `${this.basicURL}/login`
    const body = {email: loginInterface?.email, password1: loginInterface?.password1}
    return this.http.post<loginResponse>(url, body)
    .pipe(
      map(({user, token}) => this.setAuthentication(token, user)),
    catchError(err => throwError(() => err.error.message))
    )
  }

  private setAuthentication( token:string, user: User){
    this.currentState = authStatus.Authenticated
    this.currentUser = user
    localStorage.setItem('token', token)
    console.log(this.currentUser) // Here i have the userData
    return true
  }

Additionl service I am using:

 ngOnInit(): void {
    this.authService.dataEmitter.subscribe(data => console.log(data))
  }

  public currentUser:User | null = null

The issue I am facing is that even though I can successfully fetch the User data within my service method, when I try to access it in my component after logging in, it returns "null". What could be causing this discrepancy?

Answer №1

When dealing with asynchronous subscriptions, it's important to note that the next() on your Subject will be called before this.currentUser is updated.

To address this issue, you can simply emit the Subject inside of the subscription like so:

public saveData(value:loginInterface){
    this.loginUser(value).subscribe(() =>
        this.dataUserSource.next(this.currentUser)
    );
}

In addition, for clarity and consistency, consider moving the contents of the map() function inside the subscription block.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Navigating through segment tabs on Ionic 3 with a simple swipe

In the code snippet provided, segments from Ionic 3 are used with ngSwitch and ngModel. However, I am looking for a way to switch between segment tabs by simply swiping on the content area, rather than tapping the tabs at the top. Is there a way to achieve ...

Filter out unnecessary attributes while utilizing an anonymous type in ClearScript

In my development project, I am creating a .NET wrapper for the popular java-script library called Linkify.js, utilizing Microsoft's ClearScript. The challenge I am facing involves implementing the attributes property within the options object parame ...

Tips for utilizing a variable within a variable containing HTML code

Is it possible to incorporate variables in a JavaScript function that includes HTML code? Let's consider the following example: function SetCFonts() { var Color = $('#CColor').val(); var Font = $('#CFont').val(); var S ...

One way to transfer data from the back end into a two-dimensional array is by retrieving the data and then transforming it into the desired format before sending it to

How can I format backend data into a specific format using JavaScript? Even though I retrieve data from the backend, json_encode($myarry) does not display my data. $query = "SELECT * FROM LOCATIONS"; $result= mysql_query($query); while($row = mysql_fetch ...

Tips for locating the index while performing a drag and drop operation between two different containers

Can anyone help me figure out how to determine the exact index of an item when performing a jQuery drag and drop between two containers? I'm having trouble identifying the correct index, especially when it's dropped outside of its original contai ...

Choose a procedure to reset to the original setting

I'm attempting to achieve something that seems straightforward, but I'm having trouble finding a solution. I have a <select> tag with 5 <option> elements. All I want to do is, when I click a button (which has a function inside of it), ...

Lazy Load immediately loads images that are visible on the screen without needing a click

I am facing an issue with Lazy Load on my image-heavy website. I want the images to load only when a button is clicked, but currently, it only partially works. Images below the fold follow the desired behavior of loading on click, but those above the fold ...

TRPC fails to respond to the passed configuration or variables (e.g., when enabled is set to false)

Recently started using trpc and I'm trying to grasp how to utilize useQuery (which I've previously worked with in react-query): const IndexPage = () => { const { isLoading, data, isIdle } = trpc.useQuery([ "subscriber.add", { email: ...

"Utilizing Vue.js to make an AJAX request and trigger another method within a

How can I include another method within a jQuery ajax call? methods : { calert(type,msg="",error=""){ console.log("call me"); }, getData(){ $.ajax({ type: "GET", success: function(data){ / ...

Flipping a combination of CSS 3 and JavaScript cards will cause them to flip all together in unison

Hello! I came across a really cool card flip code that is IE compatible. I made some modifications to it and got it working, but there's one problem - instead of flipping the selected card, it flips all the cards. I tried modifying the JavaScript code ...

How to change a time in HH:mm format to a Date object using JavaScript

I am facing a challenge with converting two time strings to Date objects and subtracting their values. The times I have are: 14:10 and 19:02 To perform the subtraction, I attempted to parse them using the following code: var res = date1 - date2; Howev ...

The absence of typings.json in Typescript is creating an issue

As of now, I am encountering the following error during compilation: typings.json is missing In my existing packages.json, I have included the following dependency: "devDependencies": { "typescript": "^2.6.1", ... } Do you have any suggestion ...

Preserve final variable state - Angular

My function looks like this: flag: boolean = false; some_function(){ var foo = some_num_value; var bar = foo; // Storing value in a separate variable if(this.flag){ v ...

A guide on dynamically displaying a component within another component using Angular2

I am currently facing a challenge where I need to dynamically display a component within another component. When a particular record is clicked, I want to replace that record with the selected component and perform specific actions on it. Does anyone have ...

What is the proper way to import and define typings for node libraries in TypeScript?

I am currently developing a node package in TypeScript that utilizes standard node libraries such as fs, path, stream, and http. Whenever I attempt to import these libraries in a .ts file, VS Code flags the line with an error message: [ts] Cannot find m ...

React/React Hooks: Want to initiate input validation when a user deselects a checkbox

Currently, my component includes an input field and a checkbox. When the checkbox is checked, it disables the input field and clears any validation errors. However, I want to add functionality so that if the checkbox is unchecked, the input field becomes ...

Error: Cannot modify the constant property 'name' of the function."&squo;

As I attempted to enter text into the input box, an error message appeared after typing my first letter stating "cannot assign to read only property". Below is the code I am referring to: The code of the component can be found here: https://i.sstatic.net ...

The encodeURIComponent function does not provide an encoded URI as an output

Looking to develop a bookmarklet that adds the current page's URL to a specific pre-set URL. javascript:(function(){location.href='example.com/u='+encodeURIComponent(location.href)}()); Even though when I double encode the returned URL usin ...

Changing an array into a list using javascript

function convertArrayToList(inputArray) { let list = null; for (let i = inputArray.length - 1; i >= 0; i--) { list = { value: inputArray[i], rest: list }; } return list; } let result = convertArrayToList([10, 20]); console.log(JSON.stringi ...

Issue with Angular 4: Radio button defaults not being set

After hardcoding the value in component.ts, I am able to see the pre-selected radio button. However, when attempting to retrieve the value from sessionStorage, it does not work as expected. The value is visible in the console though. Could someone please ...