J'ai cette erreur après la mise à jour de mon projet angulaire
this.http.post (...). map (...). concatMap n'est pas une fonction
et voici mon code qui cause l'erreur
return this.http.post(apiURL, body, options)
.map(response => response.json())
.concatMap(response => {
// Check if the API_TOKEN is expired.
if (response.error.code == APIErrorCode.API_TOKEN_EXPIRED || response.error.code == 499) {
// Expired! Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
console.log("API_TOKEN expired.");
return this.requestAPIToken().delay(500)
.concatMap(response => this.doPost(api, body, attempts + 1));
}
console.log("API_TOKEN expired, request attempt limit reached!");
}
return Observable.of(response);
})
.catch((err, caught) => {
// Check if the session authentication token is expired.
if (authToken && err.status == 403) {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == APIErrorCode.SESSION_AUTH_TOKEN_EXPIRED) {
// Login session expired!
return Observable.of(response);
}
} catch (e) { }
}
// Check incidental bad request.
if (err.status == 400 && err.statusText == "Bad Request") {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == 400 && response.error.message
&& [ "access denied", "bad" ].includes(response.error.message.toLowerCase())) {
// Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
return this.requestAPIToken().delay(100)
.concatMap(response => this.doPost(api, body, attempts + 1));
}
console.log("Bad Request, request attempt limit reached!");
}
} catch (e) { }
}
return Observable.throw(err);
});
ça marche bien avant de mettre à jour mon projet angulaire, je ne sais pas quoi faire maintenant
3 Réponses :
Si vous venez de mettre à niveau angular, vous utilisez probablement RxJS v6. Si tel est le cas, vous devez refactoriser pour utiliser des opérateurs pipeable
Notez également que vous devez utiliser HttpClient au lieu de Http qui est obsolète depuis longtemps. Ensuite, vous pouvez également déposer la première carte avec response.json () , car HttpClient le fait automatiquement pour vous.
Gardez à l'esprit que vous devez refactoriser tous les observables dans votre code, pas seulement celui de HttpClient , mais aussi ceux avec l'opérateur delay .
Jetez un œil ici pour plus d'informations:
https://rxjs-dev.firebaseapp.com/guide/v6/migration
import { of, throwError } from 'rxjs';
import { concatMap, catchError, delay } from 'rxjs/operators';
return this.httpClient.post(apiURL, body, options)
.pipe(
concatMap(response => {
// Check if the API_TOKEN is expired.
if (response.error.code == APIErrorCode.API_TOKEN_EXPIRED || response.error.code == 499) {
// Expired! Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
console.log("API_TOKEN expired.");
return this.requestAPIToken().pipe(
delay(500),
concatMap(response => this.doPost(api, body, attempts + 1)
);
}
console.log("API_TOKEN expired, request attempt limit reached!");
}
return of(response);
}),
catchError((err, caught) => {
// Check if the session authentication token is expired.
if (authToken && err.status == 403) {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == APIErrorCode.SESSION_AUTH_TOKEN_EXPIRED) {
// Login session expired!
return of(response);
}
} catch (e) { }
}
// Check incidental bad request.
if (err.status == 400 && err.statusText == "Bad Request") {
try {
var response = JSON.parse(err._body);
if (response.error && response.error.code == 400 && response.error.message
&& [ "access denied", "bad" ].includes(response.error.message.toLowerCase())) {
// Check max attempts.
if (attempts < MAX_REQUEST_ATTEMPT) {
return this.requestAPIToken().pipe(
delay(100),
concatMap(response => this.doPost(api, body, attempts + 1)
);
}
console.log("Bad Request, request attempt limit reached!");
}
} catch (e) { }
}
return throwError(err);
})
);
Si vous utilisez la v5.5, ma réponse devrait aide aussi, mais votre problème est dans l'import d'opérateur concatMap manquant pour être précis. Soit refactoriser en opérateurs canalisables, soit ajouter simplement import 'rxjs / add / operator / concatMap';
Cette importation corrigera l'objet Observable avec Opérateur concatMap - il n'est pas là par défaut.
Pour en savoir plus sur l'importation d'opérateurs dans RxJS v5:
Extension de la réponse @Martin Adámek: - Cela devrait être quelque chose comme ceci
return this.http.post(apiURL, body, options).pipe(
map(response => response.json()),
concatMap(response => {
//REST OF THE CODE
return of(response);
}))
De plus, vous n'avez pas besoin d'écrire Observable.of (response) maintenant, vous pouvez simplement écrire of (response) Cela s'applique également à Observable.throw()
Vous utilisez probablement RxJS. Si vous souhaitez combiner map, filtrer, réduire etc ... Utilisez .pipe ()
return this.http.post(...).pipe( map(...).reduce(...) }))
De cette façon, vous pouvez combiner plusieurs méthodes.
Non, ce n'est pas ainsi que vous pouvez les combiner. Votre code est erroné, l'opérateur de carte retourne observable, il n'y a pas de méthode de réduction dessus.
Je suppose que vous utilisez RxJS v6, non? Vous devez refactoriser votre code pour utiliser des opérateurs canalisables: github.com/ ReactiveX / rxjs / blob / master / doc / pipeable-operators .md
@ MartinAdámek rxjs@5.5.12 voici ce que je reçois de la liste npm
Si vous utilisez la v5.5, ma réponse devrait également vous aider, mais votre problème est l'absence d'importations d'opérateurs
concatMappour être précis. Soit refactoriser en opérateurs canalisables, soit ajouter simplementimport 'rxjs / add / operator / concatMap'.