Angular 5 Subscribe not a function

10,370

Solution 1

you can access the resolved data in two ways

ActivatedRoute data Property which holds the static and resolved data of the current route
ActivatedRouteSnapshot: the no-observable alternative.

you need to add resolve property to the route configuration, which is an object where each key points to a resolver.

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

Approach-1

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

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

    }

Approach:2

ngOnInit() {

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


        }

STACKBLITZ DEMO

Solution 2

You're applying subscribe on Array. You should do it on Observable.

Try to apply below changes.. You can perform operations on data once you understand it's value on console.

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

UPDATE

As mentioned in Comments:

if you've defined routes like this:

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

The you should be able to get the data as:

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

Solution 3

From de angular.io doc:

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
}

That data is the observable himself. Try:

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

Remember, subscribe is the ear to an observable voice.

Solution 4

The above answers are right on, but I ran into a special case of this.

The method being called was an observable and was used in other parts of the application as an observable, yet when I ran it, it was saying the dreaded subscribe is not a function.

The issue was, I was running in Jasmine unit tests, I had defined a custom mock, and that mock was not returning an observable. In such cases it is easy to goof up the mock and return a different type then the actual function being mocked returns. Correcting my mock fixed my issue.

Share:
10,370
Reuno92
Author by

Reuno92

Updated on June 04, 2022

Comments

  • Reuno92
    Reuno92 about 2 years

    Angular return a error : Error: Uncaught (in promise): TypeError: res.users.subscribe is not a function.

    Since this morning, I don't understand what's wrong in my resolve.

    UserService.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();
        }
    }
    

    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.forEach((res: any): any => {
               this.title = res.title;
               res.users.subscribe(users =>  {
                  console.log(users);
                  this.users = users;
               });
            });
        }
    }
    

    When I log res.users, it return "function UsersResolve()" with not proto subscribe...

    The json is Array of Object like :

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

    Can the problem come from the contents of my json ?

    Originally, I wanted to train on the RxJS operator...

  • Reuno92
    Reuno92 about 6 years
    It log same thing : Object { title: 'user list, users : function UsersResolve() }
  • Pavankumar Shukla
    Pavankumar Shukla about 6 years
    I thought you've passed this static data as you mentioned in comments. it should be.. { path: 'users', component: UsersComponent, resolve: { users : UsersResolve } }... let me update the answer
  • Sujit Y. Kulkarni
    Sujit Y. Kulkarni almost 6 years
    Props for the last line. Describes Subscribe observable in one line.