I'm trying to resolve data from HTTP call from graphql apollo client. The data does not get resolved and the component using the resolver cannot access the data.
In the logs , I can see that the observable is returned first and then data from service is returned.
The data from service - {name: "s raina", id: "e78903e0-5214-11e8-93f9-8951cc65e163", country: "sa", __typename: "Cricketer", Symbol(id): "Cricketer:e78903e0-5214-11e8-93f9-8951cc65e163"}
In resolver, instead of returning an observable, I tried returning subscribing to the observable and returning the data. In this case, the component using resolver accesses undefined data after which the service gets the data.
Any help would be appreciated.
Resolver:
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { Observable } from 'rxjs';
import { Cricketer } from './types';
import { CricketerService } from './cricketer.service';
import { ActivatedRouteSnapshot } from '@angular/router/src/router_state';
@Injectable()
export class CricketerResolver implements Resolve<any> {
cricketer: any;
constructor(private cricketerService: CricketerService) {
}
resolve(route: ActivatedRouteSnapshot) {
console.log(this.cricketerService.getCricketer(route.paramMap.get('id')));
return this.cricketerService.getCricketer(route.paramMap.get('id'));
}
}
Service:
import { Injectable } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
import { map , filter } from 'rxjs/operators';
import { Query , Cricketer } from './types';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class CricketerService {
constructor(private apollo: Apollo) {}
private searchInput: BehaviorSubject<String> = new BehaviorSubject<String>('');
getAllCricketers(searchTerm: String) {
return this.apollo.watchQuery<Query>({
pollInterval: 10000,
query: gql`
query allCricketers($searchTerm: String){
allCricketers(searchTerm: $searchTerm){
name
id
country
age
}
}
`,
variables: {
searchTerm: searchTerm
}
})
.valueChanges.pipe(map(result => {
return result.data.allCricketers;
}));
}
getCricketer(id: String) {
return this.apollo
.watchQuery<Query>({
query: gql`
query getCricketer($id: String!){
getCricketer(id: $id) {
name
id
country
}
}
`,
variables: {
id: id
}
})
.valueChanges.pipe(map(result => {
console.log(result.data.getCricketer);
return result.data.getCricketer;
}));
}
addCricketer(name: String, country: String, age: Number) {
return this.apollo.mutate({
mutation: gql`
mutation addCricketer(name: $name,country: $country, age: $age){
id
name
country
age
}
`,
variables: {
name: name,
country: country,
age: age
}
});
}
updateCricketer(id: String, name: String, country: String, age: Number) {
return this.apollo.mutate({
mutation: gql`
mutation updateCricketer(id: $id , name: $name,country: $country, age: $age){
id
name
country
age
}
`,
variables: {
id: id,
name: name,
country: country,
age: age
}
});
}
updateSearchTerm(searchInput: String) {
this.searchInput.next(searchInput);
}
getSearchTerm() {
return this.searchInput.asObservable();
}
}
Component using resolver:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-cricketer-detail',
templateUrl: './cricketer-detail.component.html',
styleUrls: ['./cricketer-detail.component.css']
})
export class CricketerDetailComponent implements OnInit {
cricketer: any;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.cricketer = this.route.snapshot.data.cricketer;
}
}
Solved this by using the query method instead of watchQuery method. The watchQuery does not complete since it can emit multiple results. So the resolver did not receive the observable and did not resolve the route.
One of the members of the apollo-graphql team
From Docs
Ref- https://github.com/apollographql/apollo-angular/issues/280