Unlimited Spiral of Angular NGXS Dispatch

I am encountering an infinite loop issue when this component is loading. Does anyone have any suggestions on how to resolve this?

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { GetUser } from './state/profile.action';
import { ProfileState } from './state/profile.state';

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

export class ProfileComponent implements OnInit {
  @Select(ProfileState.userProfile) userProfile$!: Observable<UserProfile>;
  userId! :number;

  constructor(private store:Store,private router:Router) {}

  ngOnInit() {
    this.userProfile$.subscribe(userProfileData => {
      this.userId = userProfileData.id
      this.store.dispatch(new GetUser(this.userId));
        this.router.navigate(['/profile']);
       });
  }
 }

This is the service

import { Injectable } from '@angular/core';
import { HttpClient,  } from '@angular/common/http';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class UserService {
  constructor(private httpClient: HttpClient) { }

  private USER_PROFILE = 'http://localhost:8080/api/user/userProfile/';

  getUser(id:number):Observable<UserProfile>{
    return this.httpClient.get<UserProfile>(this.USER_PROFILE + id);
  }

}

And the state code


import {Action, Selector, State, StateContext} from '@ngxs/store';
import { Login, Logout} from './auth.action';
import { LoginService } from '../login.service';
import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Roles } from 'src/app/core/interfaces/role';
import { User } from 'src/app/core/interfaces/user';


export class AuthStateModel {
  accessToken: string | undefined;
      loggedInUser: User|undefined;
      username: string | undefined;
      email:string|undefined;
      roles:string |undefined;
      id: number |undefined;

}
@State<AuthStateModel>({
  name: 'auth',
  defaults: {
    loggedInUser:undefined,
    accessToken: undefined,
    username: undefined,
    email:undefined,
    roles:undefined,
    id: undefined

  }
})
@Injectable()
export class AuthState {
  result: null;

  @Selector()
  static isAuthenticated(state: AuthStateModel): boolean {
    return !!state.accessToken;
  }
  @Selector()
  static loggedInUser(state: AuthStateModel) {
    return state.loggedInUser;
  }
  @Selector()
  static role(state: AuthStateModel) {
    return state.roles;
  }
  @Selector()
  static getToken(state: AuthStateModel) {
    return state.accessToken;
  }
  @Selector()
  static loggedInUserName(state: AuthStateModel) {
    return state.username;
  }
  constructor(private loginService: LoginService) {}

  @Action(Login)
  login(ctx: StateContext<AuthStateModel>, action: Login) {
    return this.loginService.login(action.payload.username, action.payload.password).pipe(
      tap((result: { accessToken: string, username:string,email:string,roles:Roles,loggedInUser:string,id:number, password:string, name:string, token:string}) => {
      ctx.patchState({loggedInUser:result});
      window.localStorage.setItem('token',result.accessToken)
      window.localStorage.setItem('username',result.username)
      window.localStorage.setItem('email',result.email)
      window.localStorage.setItem('roles',result.roles)
      window.localStorage.setItem('id',result.id.toString())
    })
  );
  }

@Action(Logout)
logout(ctx: StateContext<AuthStateModel>) {
 this.loginService.logout()
    const state = ctx.getState();
      ctx.setState({...state,
          loggedInUser:undefined,
          accessToken: undefined,
          username: undefined,
          email:undefined,
          roles:undefined,
        });
        return state;
 };

}

**And the other State **

import { Injectable } from "@angular/core";
import { Action, Selector, State, StateContext } from "@ngxs/store";
import { tap } from "rxjs/operators";
import { UserProfile } from "src/app/core/interfaces/userProfile";
import { UserService } from "../user.service";
import { GetUser } from "./profile.action";

export class ProfileStateModel {
  userProfile: UserProfile|undefined;
}

@State<ProfileStateModel>({
  name: 'profile',
  defaults: {
    userProfile:undefined,
  }
})
@Injectable()
export class ProfileState {
  profile!: UserProfile;

@Selector()
static userProfile(state: ProfileStateModel) {
  return state.userProfile;
}
constructor(private userService: UserService) {}

@Action(GetUser)
getUser(ctx: StateContext<ProfileStateModel>, action: GetUser ){
  const state = ctx.getState();
  return this.userService.getUser(action.payload).pipe(
      tap((result) => {
        ctx.setState({
          ...state,
          userProfile:result
        });
      })
  );
  }
}

Ok so im trying to take the ID from auth.state that is arledy dispatched.. and pass id as argument to make a http call and get the userProfile data, but i get stack in infinity loop.... i dont know if this is a corect way to do it or it is good practise as code... but this is the way that i thought that could be the best for my api and front end project.... any idea??

Answer №1

import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { GetUser } from './state/profile.action';
import { ProfileState } from './state/profile.state';

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

export class ProfileComponent implements OnInit {
  @Select(ProfileState.userProfile) userProfile$!: Observable<UserProfile>;
  userId! :number;
  constructor(private store:Store,private router:Router) {}

  ngOnInit() {
    this.userProfile$.subscribe(userProfileData => {
      this.userId = userProfileData.id});
  }
  getUserProfile(){
    this.store.dispatch(new GetUser(this.userId));
    this.router.navigate(['/profile']);
  }

 }

It turned out to be easier than expected. I just modified the code like this. Thank you all for your help!

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

Having trouble accessing child directives in Angular 2 using @ContentChildren

I'm facing an issue getting nested directives from a parent directive, as @ContentChildren is not being populated. The main goal is to implement lazy-loading for images, where each image is a nested directive within the parent directive. For instan ...

Instead of returning an object, the underscore groupBy function now returns an array

Currently, I am attempting to utilize underscore to create an array of entities that are grouped by their respective locations. The current format of the array consists of pairs in this structure { location: Location, data: T}[]. However, I aim to rearran ...

Exploring bugs in Angular 14 through unit testing

After generating a new Angular project using the CLI ng new ..., I encountered an error when running npm test. The error appeared in the browser: https://i.sstatic.net/MQP0O.png and in the console as well: https://i.sstatic.net/89ghp.png I haven't ma ...

Having trouble using the Aceternity interface as it keeps giving me a type error

I am facing an issue when trying to integrate the Acternity UI component library with nextjs. The error message I keep encountering is: "Property 'pathLengths' is missing in type '{}' but required in type '{ pathLengths: MotionValu ...

Cutting-edge Angular2 modules

Starting a new Sails + Angular2 project has been quite the adventure for me. I followed the module configurations from a tutorial I found, but then realized they were different from those in Google's latest heroes tutorial. After encountering some npm ...

What could be causing the delay in loading http requests in Angular?

When attempting to update the array value, I am encountering an issue where it works inside the httpClient method but not outside of it. How can this be resolved in Angular 14? Here is a snippet from app.component.ts: ngOnInit(): void { this.httpC ...

Angular-Material: Custom Date and Time Picker Component with Seconds disabled

Is there a way to customize the datetime picker to only display Date, Hours, and Minutes, while removing seconds? Currently, the picker includes seconds as well. <mat-form-field appearance="outline" floatLabel="always"> <ma ...

Guide on implementing ng-bootstrap in AngularJS 2 (utilizing angular-cli version 1b15)

I've been attempting to incorporate ng-bootstrap into my Angular 2 project by following the guidelines provided on the official ng-bootstrap website. Here's what I have done so far: npm install <a href="/cdn-cgi/l/email-protection" class="_ ...

A method for setting values independently of [(ngModel)] within an *ngFor loop and selecting an HTML tag

I am encountering an issue with [(ngModel)], as it is syncing all my selections to the same variable. My variable is selectStations = []; Therefore, when I choose an option in one select element, it updates all select elements to have the same selected o ...

Linking a variable in typescript to a translation service

I am attempting to bind a TypeScript variable to the translate service in a similar way as binding in HTML markup, which is functioning correctly. Here's what I have attempted so far: ngOnInit() { this.customTranslateService.get("mainLayout.user ...

Error encountered when transitioning to TypeScript: Unable to resolve '@/styles/globals.css'

While experimenting with the boilerplate template, I encountered an unusual issue when attempting to use TypeScript with the default NextJS configuration. The problem arose when changing the file extension from .js to .tsx / .tsx. Various versions of NextJ ...

default selection in angular 2 dropdown menu

I'm struggling to figure out how to set a default value for a select dropdown list effortlessly. Here's my current code: <select class="form-control" ngControl="modID" #modID="ngForm"> <option *ngFor="let module of modules" [val ...

"Array.Find function encounters issues when unable to locate a specific string within the Array

Currently, I am utilizing an array.find function to search for the BreakdownPalletID when the itemScan value matches a SKU in the array. However, if there is no match found, my application throws a 'Cannot read property breakdownPalletID of undefined& ...

Is there a way to iterate over an object with predetermined keys and then utilize those keys to access another object of the same type?

What I'm attempting to do next is calculate the total value of value in pounds. However, this is causing an error message stating: TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used ...

Asynchronous data fetching adding two entries to an array

I've been experimenting with making API calls for Rick & Morty using fetch and async arrow functions, but I've run into an issue where the elements are being added to my array twice. I've tried calling the function both with and without useE ...

The initial click may not gather all the information, but the subsequent click will capture all necessary data

Issue with button logging on second click instead of first, skipping object iteration function. I attempted using promises and async await on functions to solve this issue, but without success. // Button Code const btn = document.querySelector("button") ...

Passing an object from an Angular application to a backend server in Node.js using the

I have a YAML file with the following structure: Layouts: - Name: Default Layout LayoutId : 1 ConfiguredSegments: LiveA : Height : 100 Id : LiveA Ref1A : ...

Utilizing Typescript Generics in Arrow Function to Combine Two Arguments

For instance, I am working with this code in a .tsx file extension const Add = <T,>(arg0: T, arg1: T): T => arg0 + arg1; const A = Add(1, 2); const B = Add('1', '2') However, I am encountering an issue, as there is an error m ...

Modules failing to load in the System JS framework

Encountering a puzzling issue with System JS while experimenting with Angular 2. Initially, everything runs smoothly, but at random times, System JS struggles to locate modules... An error message pops up: GET http://localhost:9000/angular2/platform/bro ...

Adding total stars options seems to be causing issues with the star rating feature in the ng framework

I have implemented the ng-starrating library in my Angular project by following this link. It was working fine without specifying the totalstars option like this: <star-rating value="{{rate}}" checkedcolor="#000000" uncheckedcolor="#ffffff"> Howeve ...