Локальное хранилище, показывающее неопределенное значение после setitem

#angular #local-storage

Вопрос:

Я храню элементы в локальном хранилище при выполнении аутентификации пользователя. При хранении элементы не определены при проверке в localstorage

В моем служебном досье :-

 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']);
  }
 

Модель:-

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

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

Где я ошибаюсь ?

Редактировать:-

Вход в систему компонента :-

 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");
    }
  }
 

В логине какие изменения необходимо внести ? ошибка в setUser (response) качестве Argument of type 'RootObject' is not assignable to parameter of type 'Result'.

Комментарии:

1. вы забываете передать запрошенные данные setUser(). Пожалуйста, смотрите ответ @MichaelD.

2. @Вирендертакур, я упомянул об ошибке, с которой столкнулся в его ответе

Ответ №1:

Где именно вызывается setUser() функция? В идеале он должен быть вызван tap оператором (для хранения сведений в локальном хранилище в качестве побочного эффекта), переданного по каналу HTTP-запроса.

 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)
  );
}
 

Обновление: типы

Учитывая , что ответ имеет тип RootObject и нет Result , типы должны быть изменены следующим образом

 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)
  );
}
 

Теперь мы отправляем первый элемент Result массива. Но почему это массив, если ответ будет содержать только один элемент? Это, возможно, должно быть скорректировано в бэкэнде, чтобы возвращать объект вместо массива.

Комментарии:

1. Его ошибка при выбрасывании — Type 'Object' is missing the following properties from type 'Result': UserName, StoreIds, BearerToken

2. @NoobCoder: Вы уверены, что ответ на HTTP-запрос соответствует Result определенному интерфейсу? Если да, попробуйте указать тип: Измените return this.http.post(...) на return this.http.post<Result>(...) .

3. @NoobCoder Угловой написан с помощью машинописного текста. Основная точка продажи-это типы, поэтому вы должны их использовать (т. Е. Не any использовать ). Это включает в себя указание аргумента типа для http.post

4. @MichaelD Да, сделал это, но после этого я столкнулся с проблемой в компоненте входа в систему. В методе входа в систему внутри, если я получаю условие Property 'IsSuccess' does not exist on type 'Result' . Я добавил ответ json в раздел РЕДАКТИРОВАНИЯ своего вопроса

5. @MichaelD Спасибо за обновленное решение. Сейчас это работает. Мне просто нужно было удалить this.authService.setUser(response); компонент входа в систему, как вы уже предлагали для входа tap .