Estoy tratando de "mapear" desde una llamada de servicio pero obtengo un error. He mirado en https://stackoverflow.com/questions/41995647/subscribe-is-not-defined-in-angular-2 y dice que para suscribirse hay que devolver desde dentro de los operadores. También tengo declaraciones de retorno.
Este es mi código:
checkLogin(): Observable<boolean> {
return this.service.getData()
.map(
response => {
this.data = response;
this.checkservice = true;
return true;
},
error => {
// debugger;
this.router.navigate(['newpage']);
console.log(error);
return false;
}
)
.catch(e => {
return e;
});
}
Registro de errores:
TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
En tu código de ejemplo, tienes a tu operador map
recibiendo dos callbacks, cuando sólo debería recibir uno. Puedes mover tu código de manejo de errores a tu callback catch.
checkLogin():Observable<boolean>{
return this.service.getData()
.map(response => {
this.data = response;
this.checkservice=true;
return true;
})
.catch(error => {
this.router.navigate(['newpage']);
console.log(error);
return Observable.throw(error);
})
}
También tendrás que importar los operadores catch
y throw
.
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
EDIT:
Ten en cuenta que devolviendo Observable.throw
en tu manejador de catch, no capturarás realmente el error - seguirá apareciendo en la consola.
Usted devuelve un Observable<booleano< mientras que su código devuelve sólo un booleano. Por lo tanto, es necesario utilizar lo siguiente
.map(response => <boolean>response.json())
Si estás usando otro servicio común checkservice
en tu caso, puedes simplemente usar
this.service.getData().subscribe(data=>console.log(data));
Esto hará que su función checkLogin()
tenga un tipo de retorno como void
checkLogin():void{
this.service.getData()
.map(response => {
this.data = response;
this.checkservice=true;
}).subscribe(data=>{ });
y podrá utilizar this.checkService
para comprobar su condición
Tengo el mismo mensaje de error exacto mientras estaba haciendo mi prueba de unidad y lanzando la excepción observable después de burlarse de mis servicios.
Lo resolví pasando la función exacta y el formato dentro de Observable.throw
.
El código real que llama al servicio y subscribe
para obtener los datos.
this.search(event).catch((e: Response) => {
if (e.status === 400) {
console.log(e.json().message);
} else if (e.url) {
console.log('HTTP Error: ' + e.status + ' ' + e.statusText,
'URL: ' + e.url, 'Info: ' + e.json().message));
}
}).finally(() => {
this.loading = false;
}).subscribe((bData) => {
this.data = bData;
});
El código dentro del servicio
search() {
return this.someService.getData(request)
.do((r) => {
this.someService.defaultHeaders.delete('skipAlert');
return r;
})
.map((r) => {
return r.businessObjectDataElements.length && r.businessObjectDataElements || null;
});
}
He burlado el SomeService y devuelve datos observables y está bien ya que tiene todos los métodos requeridos dentro de él.
someServiceApi = fixture.debugElement.injector.get(SomeService);
spyOn(someServiceApi, 'getData').and.returnValue(Observable.of({}));
El código anterior está bien, pero cuando estaba tratando de probar la condición de captura/error pasando Observable.throw({})
me estaba mostrando el error, ya que estaba esperando el retorno de tipo Response
del servicio.
Así que el retorno del servicio me daba ese error.
someServiceApi.getData
.and.returnValue(Observable.throw(new Response({status: 400, body: [], message: 'not found error'})));
Así que lo corregí replicando la función exacta esperada en mi objeto de retorno en lugar de pasar un valor de tipo Response
.
someServiceApi.getData
.and.returnValue(Observable.throw({status: 400, json: () => { return {message: 'not found error'}}, body: []}));
// see `json: () => { return {message: 'not found error'}}` inside return value