无法读取未定义角度的属性“订阅”

时间:2018-10-04 07:44:49

标签: angular rxjs observable behaviorsubject

我有一个服务UserService,它具有方法getUsers(),并且该服务在不同的角度组件之间共享。

该方法调用API并返回数据。我想保留上一个API调用的结果/状态,所以我使用BehaviorSubject来保留上一个状态,这样,如果不同的组件调用getUsers()时应该只有一个API调用,否则必须返回保持状态。

这就是我要实现的方式

private _users$: BehaviorSubject<User[]>;

constructor(private http: HttpClient) {
    this._users$ = new BehaviorSubject([]);
}

getUsers(): BehaviorSubject<User[]> {
    if (!this._getUsersState().length) {
        this._loadUsers();
        this._users$.subscribe(() => {
            return this._users$;
        });
    } else {
        return this._users$;
    }
}

_loadUsers() {
    let _users$ = this.http.get(`${this._context}/users/`);
    _users$.subscribe((users: User[]) => {
        this._users$.next(Object.assign([], users));
    });
}

_getUsersState(): User[] {
    return this._users$.getValue();
}

在组件中

this.userService.getUsers().subscribe((users: any) => {
    console.log(users);
});

但是我遇到了以下错误

ERROR TypeError: Cannot read property 'subscribe' of undefined

如果长度为0,我想让用户自动返回。

如何解决此问题?这种方法好吗?

2 个答案:

答案 0 :(得分:0)

像这样编辑服务:

private _users$ = new BehaviorSubject<User[]>(null);
public usersChanged = this._users$.asObservable();

constructor(private http: HttpClient) {
}

getUsers(): BehaviorSubject<User[]> {
    if (!this._getUsersState().length) {
        this._loadUsers();
        this._users$.subscribe(() => {
            return this._users$;
        });
    } else {
        return this._users$;
    }
}

_loadUsers() {
    let _users$ = this.http.get(`${this._context}/users/`);
    _users$.subscribe((users: User[]) => {
        this._users$.next(Object.assign([], users));
    });
}

_getUsersState(): User[] {
    return this._users$.getValue();
}

像这样编辑组件逻辑:

this.userService.usersChanged
.subscribe((users: any) => {
  if(!!users){
    console.log(users);
  } else {
    console.log("No user found!");
  }
});

有一个可观察到您的private behaviorSubject的变量是一个好习惯。因此,您只需订阅它,只要它的状态发生变化,它就会发出。

答案 1 :(得分:0)

getUsers方法应该返回一个可观察的对象,在服务中订阅可观察的对象不是一个好习惯。 如果要维护用户状态,请使用单例服务。这样声明服务中的属性:

public users: Users[] = [];


private getUsers(): Observable<Users[]> {
 if (!this.users.length) {
   return this.http.get(`${this._context}/users/`);
 }
 return Observable.of(this.users);
}

在您的组件中

this.userService.getUsers().subscribe((users: User[]) => {
    this.userService.users = users; // (or users.slice(0)
    console.log(users);
});