【问题标题】:Angular 5 Subscribe not a functionAngular 5订阅不是功能
【发布时间】:2018-11-26 15:46:42
【问题描述】:

Angular 返回一个错误:Error: Uncaught (in promise): TypeError: res.users.subscribe is not a function。

从今天早上开始,我不明白自己的决心出了什么问题。

用户服务.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class UsersService {

    private api = 'http://localhost:3000/users';
    private headers = new HttpHeaders();

    constructor(
        private http: HttpClient
    ) {}

     getAllUsers(): Observable<any[]> {
         return this.http.get<any[]>(this.api, {headers: this.headers, responseType: 'json' });
    }
}

UserResolve.ts:

import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { UsersService } from '../services/users.service';

@Injectable()
export class UsersResolve implements Resolve<any> {

    constructor(private usersService: UsersService) {}

    resolve() {
       return this.usersService.getAllUsers();
    }
}

用户组件.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import {Users} from '../_shared/models/Users';

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

export class UsersComponent implements OnInit {

    constructor(private route: ActivatedRoute) {}

    public title: string;
    public users: Users[] = [];

    ngOnInit() {
        this.route.data.forEach((res: any): any => {
           this.title = res.title;
           res.users.subscribe(users =>  {
              console.log(users);
              this.users = users;
           });
        });
    }
}

当我登录 res.users 时,它返回“function UsersResolve()”而不是 proto 订阅...

json 是对象数组,例如:

{
  id: 13246,
  guid: '46ffgd456dfs',
  name: 'John Doe',
  adress: ...
}

问题可能来自我的 json 的内容吗?

最初,我想训练 RxJS 操作符...

【问题讨论】:

  • 您没有显示您的路线定义。您确定您确实注册了 UsersResolve?
  • app.routing const appRoutes: Routes = [ ... { path: 'users', component: UsersComponent, data: { title : 'Liste des Utilisateurs', users : UsersResolve } } ]; @NgModule({ ... providers: [UsersResolve, UserService] 我以为否则 Angular 会警告我。
  • 啊,有一个错误:你将UsersResolve-class的引用分配给data.users,它实际上不会以这种方式运行。请参阅 Pavan 的回答。
  • 请点击对您最有帮助的答案左侧的复选标记来关闭您的问题

标签: angular observable httpclient subscribe


【解决方案1】:

您正在对 Array 应用订阅。你应该在 Observable 上做。

尝试应用以下更改.. 一旦您了解数据在控制台上的价值,您就可以对数据执行操作。

UserComponent.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {Users} from '../_shared/models/Users';

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

export class UsersComponent implements OnInit {

    constructor(private route: ActivatedRoute) {}

    public title: string;
    public users: Users[] = [];

    ngOnInit() {
        this.route.data.subscribe(data => console.log(data));
    }
}

更新

如评论中所述:

如果你定义了这样的路由:

const appRoutes: Routes = 
[ ... 
 { path: 'users',
   component: UsersComponent,
   resolve: { 
     users : UsersResolve 
   } 
 } 
];

你应该能够得到数据:

ngOnInit() {
        this.route.data.subscribe(data => console.log(data['users']));
    }

【讨论】:

  • 它记录了同样的事情:Object { title: 'user list, users : function UsersResolve() }
  • 我以为你已经传递了这个静态数据,正如你在 cmets 中提到的那样。它应该是.. { path: 'users', component: UsersComponent, resolve: { users : UsersResolve } }... 让我更新答案
【解决方案2】:

来自 de angular.io 文档:

interface ActivatedRoute {
  snapshot: ActivatedRouteSnapshot
  url: Observable<UrlSegment[]>
  params: Observable<Params>
  queryParams: Observable<Params>
  fragment: Observable<string>
  data: Observable<Data>
  outlet: string
  component: Type<any> | string | null
  get routeConfig: Route | null
  get root: ActivatedRoute
  get parent: ActivatedRoute | null
  get firstChild: ActivatedRoute | null
  get children: ActivatedRoute[]
  get pathFromRoot: ActivatedRoute[]
  get paramMap: Observable<ParamMap>
  get queryParamMap: Observable<ParamMap>
  toString(): string
}

该数据本身就是可观察的。试试:

this.route.data.subscribe(data =>  {
      console.log(data);
   });
});

请记住,订阅是可观察到的声音。

【讨论】:

  • 最后一行的道具。在一行中描述订阅 observable。
【解决方案3】:

您可以通过两种方式访问​​已解析的数据

ActivatedRoute data 保存当前路由的静态和解析数据的属性
ActivatedRouteSnapshot:不可观察的替代方案。

您需要在路由配置中添加resolve 属性,这是一个对象,其中每个键都指向一个解析器。

    const appRoutes: Routes = [{ path: 'users', component: UsersComponent, 
         data: { title : 'Liste des Utilisateurs'},
          resolve:{ users : UsersResolve } } 
]

方法一

 ngOnInit() {
        this.route.data.subscribe(value=>{

   this.title=value.title;
    this.users=value.user;
});

    }

方法:2

ngOnInit() {

       this.title=this.route.snapshot.data.title;
        this.users=this.route.data.snapshot.user;


        }

STACKBLITZ DEMO

【讨论】:

    【解决方案4】:

    上面的答案是正确的,但我遇到了一个特殊情况。

    被调用的方法是一个 observable,并在应用程序的其他部分作为 observable 使用,但是当我运行它时,它说的是可怕的 subscribe is not a function

    问题是,我在 Jasmine 单元测试中运行,我定义了一个自定义模拟,并且该模拟没有返回可观察的。在这种情况下,很容易搞砸模拟并返回不同的类型,然后被模拟的实际函数返回。更正我的模拟解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-23
      • 2018-11-26
      • 2018-01-13
      • 1970-01-01
      • 2018-09-02
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多