Je construis une application dans laquelle les utilisateurs doivent se connecter sur un certain sous-domaine. C'est différent pour chaque utilisateur. Ainsi, sur la page de connexion, l'utilisateur s'est connecté avec sous-domaine, nom d'utilisateur et mot de passe. Avant de faire des appels API, je dois enregistrer le sous-domaine dans le stockage ionique. Ce n'est pas un problème, mais comment j'utiliserai ce sous-domaine en tant que const dans mon service api parce que c'est une asynchrone, il ne donne pas la valeur tout de suite.

C'est ma fonction dans le service

startFunction(entry) {
    this.storage.get('subdomain').then(
        result => {
            return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers}
            );
        }
    )

}

Et ce composant ma page

otherFunction(){
    this.GetApi.startFunction(entry).subscribe(
    result => {
        console.log(result)
    },
    err => {
        console.log(err);
    });
}

Mais cela donne une erreur cannot subscribe to undefined, comment utiliser la valeur de stockage asynchrone dans une promesse / observable. Le mieux serait une sorte de const que je peux utiliser pour chaque fonction du service api.

1
Maarten Heideman 27 janv. 2019 à 00:11

3 réponses

Meilleure réponse

Je tirerais parti d'un HttpInterceptor ici pour éviter d'obtenir le sous-domaine pour toutes les requêtes http. HttpInterceptor est génial! :RÉ

Donc, ce que vous pourriez faire, créer un intercepteur, comme il est dit dans votre question, vous définissez le sous-domaine avant de faire une requête http, donc en supposant qu'il y ait toujours un sous-domaine lorsque vous faites une requête http.

Je vois également que vous définissez des en-têtes. Si les en-têtes sont identiques pour tous, vous pouvez également le faire dans l'intercepteur. Je ne l'inclus pas ici cependant.

Voici donc à quoi pourrait ressembler votre intercepteur:

@Injectable()
export class NoopInterceptor implements HttpInterceptor {

  constructor(private storage: Storage) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const obs = Observable.fromPromise(this.storage.get('subdomain'));
      return obs.flatMap(data => {
        console.log(data); // here should be your subdomain
        // add your subdomain, and the rest of the url
        const apiReq = req.clone({ url: `${data}${req.url}` });
        return next.handle(apiReq);

    })
  }
}

Cela signifie alors que dans votre requête, ignorez le sous-domaine, et ajoutez simplement la partie de cette dernière url, puisque nous ajoutons le sous-domaine dans l'intercepteur:

return this.http.post(this.apiUrl, entry, { headers: HEADER.headers}

Voici un exemple factice où je viens de définir les données dans le stockage de l'intercepteur, vous le feriez là où vous le faites actuellement.

Notez que vous n'avez pas besoin de stringifier la charge utile.

StackBlitz

1
AJT82 29 janv. 2019 à 18:33

La réponse @Bergi est correcte. Mais vous devez vous abonner après la résolution de la promesse, car votre promesse renvoie un observable:

startFunction(entry) {
    return this.storage
               .get('subdomain')
               .then(result => this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers});
}

Et:

otherFunction(){
    this.GetApi.startFunction(entry)
               .then( observable$ => observable$.subscribe( result => 
    {
        console.log(result)
    },
    err => {
        console.log(err);
    }))
}
0
Melchia 26 janv. 2019 à 22:53

Vous devez return la promesse du startFunction:

startFunction(entry) {
    return this.storage.get('subdomain').then(result => {
//  ^^^^^^
        return this.http.post(result + this.apiUrl, JSON.stringify(entry), { headers: HEADER.headers};
    });
}

Puis utilisez then au lieu de subscribe:

otherFunction(){
    this.GetApi.startFunction(entry).then(result => {
        console.log(result)
    }, err => {
        console.log(err);
    });
}
1
Bergi 26 janv. 2019 à 21:47