NoobCoder
NoobCoder

Reputation: 503

LocalStorage showing undefined after setitem

I am storing items on localstorage when doing authentication user. Upon storing the items are undefined when checking in localstorage

In my service file :-

import { Result } from '../models/user';
dt: number = new Date().getTime();
 
  loginForm(data: any): Observable<any> {
   return this.http
  .post(`${environment.baseUrl}/api/login`, data, this.httpOptions)
  .pipe(
    retry(2),
    catchError(this.handleError)
  );
  }

  setUser(resp: Result) {
    localStorage.setItem('username', JSON.stringify(resp.UserName));
    localStorage.setItem('token', JSON.stringify(resp.BearerToken));
    localStorage.setItem('lastVisit', String(this.dt));
    localStorage.setItem('storeids', JSON.stringify(resp.StoreIds));
    this.router.navigate(['/home']);
  }

model:-

export interface Result {
    UserName: string;
    StoreIds: string;
    BearerToken: string;
}

export interface RootObject {
    IsSuccess: boolean;
    ErrorMsg: string;
    ErrorCode?: any;
    Result: Result[];
}

Where am I going wrong ?

EDIT:-

Component login :-

login() {
    if (this.myGroup.valid) {
      this.authService.loginForm(this.myGroup.value).subscribe(response => {
        if (response.IsSuccess == true) {
          console.log(response);
          this.authService.setUser(response);
        }
      }, error => {
        console.error(error);
      });
    } else {
      alert("error ! login failed");
    }
  }

In login what changes have to be done ? error in setUser (response) as Argument of type 'RootObject' is not assignable to parameter of type 'Result'.

Upvotes: 0

Views: 159

Answers (1)

Barremian
Barremian

Reputation: 31105

Where exactly is the setUser() function called? Ideally it would be called in the tap operator (to store the details in local storage as a side-effect) piped to the HTTP request.

loginForm(data: any): Observable<any> {
  return this.http.post(
    `${environment.baseUrl}/api/login`, 
    data, 
    this.httpOptions
  ).pipe(
    tap((resp: Result) => this.setUser(resp)),
    retry(2),
    catchError(this.handleError)
  );
}

Update: types

Given that the response is of type RootObject and not Result, the types have to changed the following way

loginForm(data: any): Observable<RootObject> {  // <-- Observable of type `RootObject`
  return this.http.post<RootObject>(
    `${environment.baseUrl}/api/login`, 
    data,
    this.httpOptions
  ).pipe(
    tap((resp: RootObject) => this.setUser(resp.Result[0] as Result)),
    retry(2),
    catchError(this.handleError)
  );
}

Now we are sending the first element of the Result array. But why is it an array if the response would only contain one element? That perhaps must be adjusted in the backend to return an object instead of an array.

Upvotes: 2

Related Questions