Angular5 Как использовать Http Observable - PullRequest
0 голосов
/ 22 мая 2018

У меня проблема с HTTP-запросами на Angular5.У меня есть два компонента (" LoginComponent ", " WellcomeComponent ") и один сервис (" AuthService ").

Я использую сервис аутентификации для обработки HTTP-запросов, а также этот сервис является мостом между двумя компонентами.

Я могу получать и публиковать запросы от службы, но не могу правильно использовать результаты из-за наблюдаемых вещей.Я не опытный разработчик Angular, поэтому не могу найти решение.

Итак, теперь я объясняю шаг за шагом.Я напишу здесь весь свой код, и все шаги будут подписаны .. Step_ текстом в коде, чтобы вы могли выполнять все шаги под этим знаком.


LoginComponent

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html'
})
export class LoginComponent {

    loginUserData = {}

    constructor(
        private _auth: AuthService,
        public router:Router ){
            //SOMETHING
        }

    //CLICK FORM SUBMIT BUTTON
    public onSubmit(values:Object):void {

        //SET USER DATA WITH FORM VALUES
        console.log("LoginStep_1 - Hello")

        this._auth.getToken(this.loginUserData)
        // CHECK TOKEN

        // IF VERIFIED
            console.log('LoginStep_2 - Token Verified');

            this._auth.setUserData(this.loginUserData['username']);
            console.log('LoginStep_3 - SetUserData Finished');

            this.router.navigate(['/wellcome'])
            console.log("LoginStep_4 - Navigated");
    }

}

AuthService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';

@Injectable()
export class AuthService {

    private _tokenUrl = "http://localhost:8000/api/auth/token/";
    private getUserInfoUrl = "http://127.0.0.1:8000/api/userInfo/?username="
    private userInfo : any;

    constructor(
        private http: HttpClient,
        private _router: Router
    ) { }

    getToken(user){
        console.log("getToken_Step1 - Hello");

        this.http.post<any>(this._tokenUrl, user)
        .subscribe(
            res => {

                //getToken_Step2 : SET TOKEN SOMEWHERE
                console.log("getToken_Step2 - Token : ", res.token);

            },
            err => console.log(err)
        );

        console.log("getToken_Step3 - Bye");
    }

    setUserData(userName){
        console.log("setUserData_Step1 - Hello");

        this.http.get<any>(this.getUserInfoUrl+userName)
        .subscribe(
            res=>{

                //setUserData_Step2 : SET USERINFO SOMEWHERE
                console.log("setUserData_Step2 - User Info : ", res);

            },
            err=>{
                console.log(err);
            }
        )

        console.log("setUserData_Step3 - Bye");
    }

    getUserData(){
        console.log("getUserData_Step1 - Hello");
        return this.userInfo;
    }

}

WellcomeComponent

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../../auth.service';

@Component({
  selector: 'app-wellcome',
  templateUrl: './wellcome.component.html',
  styleUrls: ['./wellcome.component.scss'],
})
export class WellcomeComponent implements OnInit {

    constructor(private _auth: AuthService){ }

    ngOnInit() {
        console.log("Wellcome_Step1 - Hello");
        let userInfo = this._auth.getUserData();
        console.log("Wellcome_Step2 - Show User Info");
    }

}

Если вы посмотрите коды, есть много console.log ("Шаг .. , я объясняю, что я хочу сделать, используя их.

КороткоЯ могу сказать, что хочу видеть их в этом порядке на экране консоли:

  1. LoginStep_1 - Hello: Этот шаг будет работать, нажав кнопку отправки в форме
  2. getToken_Step1 - Hello: Перейти к службе авторизации
  3. getToken_Step2 - токен: Получить токениз API и напишите его localStorage
  4. getToken_Step3 - пока
  5. LoginStep_2 - токен проверен: затем вернитесь и проверьтеэтот токен.
  6. setUserData_Step1 - Hello
  7. setUserData_Step2 - Информация о пользователе: Получить информацию о пользователе из API и написать ее localStorage
  8. setUserData_Step3 - Пока
  9. LoginStep_3 - SetUserData Закончено: Я получил токен, проверил его, получил информацию о пользователе и написал ее.Теперь я могу перейти к навигации.
  10. Wellcome_Step1 - Hello: Навигация с логина
  11. getUserData_Step1 - Hello: получить всю информацию, написанную LoginComponent
  12. Wellcome_Step2 - Показать информацию о пользователе: Делать то, что вы хотите с информацией пользователя

Эти шаги я хочу видеть на экране журнала консоли, но я не вижу их в правильном порядке.Мой вывод на консоль сильно отличается от моего ожидания.Потому что я не знаю, как использовать угловые 5 наблюдаемых, поэтому не могу обработать возвращаемое значение из API.

Моя консоль выводит что-то вроде этого:

  1. LoginStep_1- Hello
  2. LoginStep_3 - SetUserData Закончено
  3. getToken_Step1 - Hello
  4. getToken_Step2 - токен

... Вот почему этот заказ?Как я могу это исправить?


Итак, как мне это сделать?Я хочу взять токен и информацию о пользователе по LoginComponent и использовать их из компонента WellCome.

Как я уже сказал, я не опытный кодер, поэтому, возможно, решение очень простое, но не может найти.

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

По сути, вы должны реализовать вызов функции для возврата либо promise, либо observable (он же асинхронный).AuthService выглядит примерно так (адаптировано из вашего вопроса):

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';

import {Observable, of} from 'rxjs';

@Injectable()
export class AuthService {
  constructor(private http: HttpClient) {}

  // private _tokenUrl = "http://localhost:8000/api/auth/token/";

  // This is just a mock URL that returns a response (200 OK)
  private _tokenUrl =
      "https://bikewise.org:443/api/v2/incidents?page=1&proximity_square=100";
  // private getUserInfoUrl = "http://127.0.0.1:8000/api/userInfo/?username=";
  private userInfo: any;

  // can improve with getter/setter instead of exposing directly
  private isLoggedIn: boolean = false;

  isLoggedInObservable: Observable<boolean>;

  getToken(user): Promise<any> {
    console.log("getToken_Step1 - Hello");

    return new Promise(resolve => {

      // this.http.post<any>(this._tokenUrl, user)
      // fake request to make sure always get a response
      this.http.get<any>(this._tokenUrl)
          .subscribe(
              res => {

                // getToken_Step2 : SET TOKEN SOMEWHERE
                console.log("getToken_Step2 - Token : ", "token_1234");

                console.log("getToken_Step3 - Bye");
                // resolve(res.token);
                resolve("token1234");

              },
              err => {
                console.log(err);

                throw new Error('Unauthorized...');

              });
    })
  }

  setUserData(userName) {
    console.log("setUserData_Step1 - Hello");

    // If this is a real request, make sure to implement a promise/observable
    // return
    // this.http.get<any>(this.getUserInfoUrl + userName)

    // setUserData_Step2 : SET USERINFO SOMEWHERE
    console.log("setUserData_Step2 - User Info : ");

    console.log("setUserData_Step3 - Bye");
    this.isLoggedIn = true;
    this.isLoggedInObservable = of(true);
  }

  getUserData() {
    console.log("getUserData_Step1 - Hello");
    return this.userInfo;
  }

  logOut() {
    this.isLoggedInObservable = of(false);
    this.isLoggedIn = false;
  }

  isLogged(): boolean { return this.isLoggedIn; }
}

Вам также нужно настроить AuthGuard для маршрутизации, чтобы отслеживать, вошел ли пользователь в систему или нет.

Вот рабочий пример stackblitz . Открыть консоль для отслеживания статуса

Кроме того, вы всегда можете кэшировать свой логин в браузере localStorage, чтобы улучшить взаимодействие с пользователем.Опять же, это адаптировано из вашего кода.Есть много вещей, которые можно улучшить из вашего кода.Дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 22 мая 2018

Поскольку ваши запросы к бэкэнду асинхронны, их выполнение займет некоторое время.Поэтому Angular перейдет к другим задачам: console.log('LoginStep_2 - Token Verified'); и console.log('LoginStep_3 - SetUserData Finished'); до завершения getToken() и setUserData().

Вы можете переместить подписку на компонент

В вашем AuthService

    getToken(user){
        console.log("getToken_Step1 - Hello");

        return this.http.post<any>(this._tokenUrl, user)
        // subscribe moves to component
    }

В вашем компоненте

this._auth.getToken(this.loginUserData)
  .subscribe(
    res => {

      //getToken_Step2 : SET TOKEN SOMEWHERE
      console.log("getToken_Step2 - Token : ", res.token);
    },
    err => console.log(err)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...