angulaire 2 ngIf avec observables?
J'ai une question très simple service et de son travail consiste à obtenir soit 200 ou 401 de l'api/authentifier url.
auth.service.ts
@Injectable()
export class AuthService {
constructor(private http: Http) {
}
authenticateUser(): Observable<any> {
return this.http.get(AppSettings.authenitcationEnpoint)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response;
return body || {};
}
private handleError(error: Response) {
let errMsg: string;
if (error instanceof Response) {
errMsg = `${error.status} - ${error.statusText || ''}`;
} else {
errMsg = error.toString();
}
return Observable.throw(errMsg);
}
}
maintenant je veux l'utiliser dans mon code html, je sais que je peux créer un abonné et en fonction de la réponse ou un code d'erreur définir une variable, mais mon problème est que je vais avoir à dupliquer le code dans tous les sens. Je veux très simple
<div *ngIf="authService.AuthenticateUser()">my content</div>
Si son 401 qui est à venir à partir de handleError alors de le cacher sinon afficher la div.
Son comme obtenir une valeur booléenne à partir d'Observables. J'ai aussi AuthGuard.
authguard.ts
@Injectable()
export class AuthGuard implements CanActivate {
private isActive: boolean = true;
constructor(private authService: AuthService, private router: Router) {
}
canActivate(): boolean {
this.authService.authenticateUser()
.subscribe(() => {},
error => {
if (error.indexOf("401") >= 0) {
let link = ['contactus'];
this.router.navigate(link);
this.isActive = false;
}
});
return this.isActive;
}
}
Je ne peux pas utiliser authGuard.canActive() comme dans ngIf. Est-il un moyen plus facile de le faire sans duplication de code. Je suis assez sûr AuthGuard n'est pas le travail comme il doit retourner true, à chaque fois, parce que abonnez-vous va prendre du temps.
app.composante.ts
export class AppComponent {
private isAuthenticated: boolean = false;
constructor(private authService: AuthService,private authGuard: AuthGuard) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
}
}
la maison.composante.ts
export class HomeComponent implements OnInit {
constructor(private http: Http, private authService: AuthService, private utilityService: UtilityService, private homeService: HomeService, private factoryService: FactoryService, private supplierService: SupplierService, private businessAreaService: BusinessAreaService, private router: Router) {
this.authService.authenticateUser()
.subscribe(response => {
if (response.status == 200)
this.isAuthenticated = true;
},
error => {
if (error.indexOf("401") >= 0)
this.isAuthenticated = false;
});
this.customData = new CustomData(http);
}
}
Comme vous pouvez le voir beaucoup de code dupliqué. J'essaie d'éviter les doubles emplois.
Quand je l'appelle mon api un pop up s'affiche pour entrer dans windows nom d'utilisateur/mot de passe pour l'Authentification windows. Je n'obtiens 401 jusqu'à ce que je annuler cette pop up. si je veux cacher mon menu + la maison de la composante.
Dans mon service je reçois la réponse:200 carte
non autorisé:401 dans attraper bloc
.ts
de la composante.Et si vous n'avez pas
subscribe
à une observable, vous n'aurez jamais aucun résultat.Enfin, une fois que vous avez un composant qui récupère le résultat d'un appel http (d'un service), vous pouvez vous y abonner pour enregistrer la valeur pour l'afficher dans votre vue OU de l'utilisation de la
async
pipe.
OriginalL'auteur Kamran Pervaiz | 2016-12-05
Vous devez vous connecter pour publier un commentaire.
Ici, vous êtes de retour d'une observables et non la valeur:
Ce que vous devez faire est de créer une propriété dans votre service, et ensuite d'utiliser cette propriété dans votre code html et non pas la fonction qui s'abonne à l'observable. Quelque chose comme:
Et puis, dans votre code html, il suffit d'utiliser:
Une autre façon de le faire est d'utiliser le
async
pipe. Ainsi, la vue va attendre l'observation de retour avant de faire digérer la cicle. Quelque chose comme:Il ne sera pas mis à jour? Pourquoi dis-tu cela?
Arf c'est pas ce que je voulais exactement mon mauvais. Il ne sera pas en mesure de souscrire à la modification de cette valeur. Avec qui est dommage dans ce cas et en général. Si il a une observable, il faut le garder 🙂
c'est une bonne suggestion, mais 401 ira à bloc catch, dois-je donc faire de faux dans les attraper et de vrai dans le cas où il va à la carte?
Cela dépend de votre mise en œuvre. Si vous regardez la déclaration de niveau de, la variable a la valeur false par défaut. Alors, seulement quand vous avez un 200/201 code d'état, vous aurez besoin de changer la variable à true. Si la 401 est retourné, la variable est déjà faux, de sorte que vous n'avez pas besoin de faire quoi que ce soit catch(). J'ai supposé que vous pouvez vous authentifier uniquement lorsque vous n'êtes pas authentifié. Une autre chose est que ce service doit être un singleton, alors la variable est attribuée qu'une seule fois. Mis au service du chargeur en un fournisseur d'applications de niveau, pas à un enfant de module...
OriginalL'auteur Bruno João