http - example - observable angular 6
¿Cómo encadenar llamadas Http en Angular2? (3)
Puede hacerlo utilizando el operador
mergeMap
.
Angular 4.3+ (usando
HttpClientModule
) y RxJS 6+
import { mergeMap } from ''rxjs/operators'';
this.http.get(''./customer.json'').pipe(
mergeMap(customer => this.http.get(customer.contractUrl))
).subscribe(res => this.contract = res);
Angular <4.3 (usando
HttpModule
) y RxJS <5.5
Importe el
map
operadores y
mergeMap
, luego puede encadenar dos llamadas de la siguiente manera:
import ''rxjs/add/operator/map'';
import ''rxjs/add/operator/mergeMap'';
this.http.get(''./customer.json'')
.map((res: Response) => res.json())
.mergeMap(customer => this.http.get(customer.contractUrl))
.map((res: Response) => res.json())
.subscribe(res => this.contract = res);
Algunos detalles más aquí: http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http
Puede encontrar más información sobre el operador mergeMap here
Soy nuevo en Angular2 y Http Observable. Tengo un componente que llama al servicio Http y devuelve Observable. Entonces me suscribo a ese Observable y funciona bien.
Ahora, quiero, en ese componente, después de llamar al primer servicio Http, si la llamada es exitosa, llame a otro servicio Http y devuelva ese Observable. Entonces, si la primera llamada no es exitosa, el componente devuelve ese Observable, al contrario devuelve el Observable de la segunda llamada.
Entonces, la pregunta es, ¿cuál es la mejor manera de encadenar llamadas Http? ¿Hay alguna manera elegante, por ejemplo, como las mónadas?
También puedes encadenar Promesas también. Por este ejemplo
<html>
<head>
<meta charset="UTF-8">
<title>Chaining Promises</title>
</head>
<body>
<script>
const posts = [
{ title: ''I love JavaScript'', author: ''Wes Bos'', id: 1 },
{ title: ''CSS!'', author: ''Chris Coyier'', id: 2 },
{ title: ''Dev tools tricks'', author: ''Addy Osmani'', id: 3 },
];
const authors = [
{ name: ''Wes Bos'', twitter: ''@wesbos'', bio: ''Canadian Developer'' },
{ name: ''Chris Coyier'', twitter: ''@chriscoyier'', bio: ''CSS Tricks and Codepen'' },
{ name: ''Addy Osmani'', twitter: ''@addyosmani'', bio: ''Googler''},
];
function getPostById(id) {
// create a new promise
return new Promise((resolve, reject) => {
// using a settimeout to mimic a database/HTTP request
setTimeout(() => {
// find the post we want
const post = posts.find(post => post.id == id);
if (post) {
resolve(post) // send the post back
} else {
reject(Error(''No Post Was Found!''));
}
},200);
});
}
function hydrateAuthor(post) {
// create a new promise
return new Promise((resolve, reject) => {
// using a settimeout to mimic a database/http request
setTimeout(() => {
// find the author
const authorDetails = authors.find(person => person.name === post.author);
if (authorDetails) {
// "hydrate" the post object with the author object
post.author = authorDetails;
resolve(post);
} else {
reject(Error(''Can not find the author''));
}
},200);
});
}
getPostById(4)
.then(post => {
return hydrateAuthor(post);
})
.then(post => {
console.log(post);
})
.catch(err => {
console.error(err);
});
</script>
</body>
</html>
Usar rxjs para hacer el trabajo es una muy buena solución. Es fácil de leer ? No lo sé.
Una forma alternativa de hacer esto y más legible (en mi opinión) es usar await / async .
Ejemplo:
async getContrat(){
//get the customer
const customer = await this.http.get(''./customer.json'').toPromise();
//get the contract from url
const contract = await this.http.get(customer.contractUrl).toPromise();
return contract; // you can return what you want here
}
Entonces llámalo :)
this.myService.getContrat().then( (contract) => {
// do what you want
});
o en una función asíncrona
const contract = await this.myService.getContrat();
También puede usar try / catch para administrar el error:
let customer;
try {
customer = await this.http.get(''./customer.json'').toPromise();
}catch(err){
console.log(''Something went wrong will trying to get customer'');
throw err; // propagate the error
//customer = {}; //it''s a possible case
}