A2: получить данные от апи и объявить переменные глобально
Помогите получить данные пользователя из АПИ, присвоить переменным, которые использовать в любом из компонентов
Делаю так: АПИ: {"login": "test", "ban": 0} Корневой app.module.ts: ... import { UserService } from './shared/user.service'; ... providers: [ UserService ], ... user.service.ts Вот тут начинаются проблемы, мое понимание углового пока на уровне копипаста import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; export class User { login: string; ban: number; } @Injectable() export class UserService { constructor(private http: HttpClient) { } user: User ngOnInit() { this.http.get('/server/api/userService').subscribe((data: User) => { this.user = data; test = this.user['login']; // <- В этом моменте непонятности } ); } } Помогите хотя бы для начала записать в консоль логин пользователя, typescript пока вообще не понимаю Правильно ли вообще я вижу алгоритм? 1) Сервисом загружаю данные с сервера, присваиваю переменным значения 2) Загружаю сервис в главный модуль 3) В любом из компонентов, без дополнительных инклудов могу использовать переменные {{user.login}} |
Здравствуйте. Я бы вам советовал прочитать о таком явлении как сервисы и dependency injection. Хотябы здесь: metanit.com
Ваш код по сути просто недописан. У вас есть сервис, который уже читает данные из АПИ. Сам факт объявления его как сервис делает его доступным внутри всего приложения. Осталось расширить интерфейс сервиса методами доступа к даннам из внешних компонентов. Дописываем UserService: getUserInfo(){ return this.user; } Встраиваем сервис в компонент. Например в AppComponent. Опускаю здесь ненужные подробности и возможно допуская кое-какие ошибки. Вам ведь нужен подход? :о) : export class AppComponent { currentUser: User; constructor( userServise: UserService // Вот момент встраивания сервиса ){} onInit(){ this.currentUser = this.userServise.getUserInfo(); } } |
sniffysko, спасибо за помощь, но пока не получается.
Вот так работает, но в пределах одного компонента. А на остальные не распространяется. А я хотел, чтобы переменные {{ user?.login }} были видны глобально, во всех шаблонах app.component.ts import { Component } from '@angular/core'; //import { UserService, User } from './shared/user2.service'; import { HttpClient } from '@angular/common/http' export class User { login: string; ban: number; } @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { user: User constructor(private http: HttpClient) {} ngOnInit() { this.http.get('/server/api/userService').subscribe((data: User) => (this.user = data)) } } |
Vadya,
Ваш код не работает, потому что такие хуки как ngOnInit они как бы для компонентов. Снаружи никто метод этого класса не вызывает судя по коду. import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; import { of } from 'rxjs'; export class User { login: string; ban: number; } @Injectable() export class UserService { constructor(private http: HttpClient) {} user: User getUser() { if (this.user) { return of(this.user); } return this.http.get('/server/api/userService').pipe( tap((data: User) => this.user = data) ); } } |
Перенес этот код в отдельный файл, user.module.ts
В app.module.ts сделал импорт и providers: [ UserService ] Теперь непонятно, как этот сервис соберет данные и расшарит их для всех компонентов. Ведь даже запроса к апи он не делает Мне где то надо единожды вызвать функцию getUser? Пока не понимаю даже как вызвать ее в шаблоне компонента |
Vadya,
Нужно вызывать метод getUser сервиса UserService в каждом из компонентов, нуждающихся в юзере. Например, так export class AppComponent { currentUser: User; constructor( userServiсe: UserService // Вот момент встраивания сервиса ){} onInit(){ this.userServiсe.getUser().subscribe(user => this.currentUser = user); } } |
Получается по сути это как у меня здесь: https://javascript.ru/forum/518052-post3.html (#3)?
То есть если мне нужны данные пользователя в header.component и footer.component, то из каждого компонента будет произведен запрос к серверу? |
Цитата:
|
Вот теперь все встало на свои места. Я почему-то думал, что в угловом как-то можно сделать все в одном месте и после этого не трогать модули компонентов.
|
У меня еще один вопрос появился. Данные пользователя я получил, а в роутер передать через функцию не могу. Вот код с комментарием, где не получается:
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router"; import { Observable } from "rxjs"; import { UserService } from './user.service'; import { Injectable } from '@angular/core'; @Injectable() export class AuthGuard implements CanActivate { user: any; constructor(private userService: UserService, private router: Router) { } public isAuthenticated(): any { this.userService.getUser().subscribe(data => { this.user = data; if(this.user['login'] !== false) {return true;} }); } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> | boolean{ if(this.isAuthenticated()) { // <- Сюда не проходит true return true; } else { this.router.navigate(['/login']); } } } |
Часовой пояс GMT +3, время: 01:52. |