Вопрос:

Angular2 обрабатывает http ответ

typescript angular

179358 просмотра

3 ответа

964 Репутация автора

У меня просто вопрос относительно структурирования и обработки ответов на запросы http внутри службы. Я использую Angular2.alpha46 Typescript (только начал тестировать его, что мне нравится ... Ps .. Спасибо всем людям, которые работали над этим и помогали через github)

Итак, возьмите следующее:

Вход-form.component.ts

import {Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2';
import {UserService} from '../../shared/service/user.service';
import {Router} from 'angular2/router';
import {User} from '../../model/user.model';
import {APP_ROUTES, Routes} from '../../core/route.config';

@Component({
    selector: 'login-form',
    templateUrl: 'app/login/components/login-form.component.html',
    directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
})

export class LoginFormComponent {
    user: User;
    submitted: Boolean = false;

    constructor(private userService:UserService, private router: Router) {
        this.user = new User();
    }

    onLogin() {
        this.submitted = true;

        this.userService.login(this.user,
            () => this.router.navigate([Routes.home.as]))
    }
}

из этого компонента я импортирую свой userService, в котором будет размещен мой http-запрос для входа в систему, и сервис выглядит так:

user.service.ts

import {Inject} from 'angular2/angular2';
import {Http, HTTP_BINDINGS, Headers} from 'angular2/http';
import {ROUTER_BINDINGS} from 'angular2/router';
import {User} from '../../model/user.model';

export class UserService {

    private headers: Headers;

    constructor(@Inject(Http) private http:Http) {
    }

    login(user: User, done: Function) {
        var postData = "email=" + user.email + "&password=" + user.password;

        this.headers = new Headers();
        this.headers.append('Content-Type', 'application/x-www-form-urlencoded');

        this.http.post('/auth/local', postData, {
                headers: this.headers
            })
            .map((res:any) => res.json())
            .subscribe(
                data => this.saveJwt(data.id_token),
                err => this.logError(err),
                () => done()
            );
    }

    saveJwt(jwt: string) {
        if(jwt) localStorage.setItem('id_token', jwt)
    }

    logError(err: any) {
        console.log(err);
    }
}

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

В данный момент в моем сервисе под логином я в настоящее время не обрабатываю ответ. Я просто возвращаюсь к исходному компоненту, но я чувствую, что это не правильный путь? Может ли кто-то пролить свет на то, что они будут делать в этом типичном сценарии? Я обработал бы ответ в первом параметре функции подписки как:

 login(user: User, done: Function) {
     var postData = "email=" + user.email + "&password=" + user.password;

    this.headers = new Headers();
    this.headers.append('Content-Type', 'application/x-www-form-urlencoded');

    this.http.post('/auth/local', postData, {
            headers: this.headers
        })
        .map((res:any) => res.json())
        .subscribe(
            (data) => {
                // Handle response here
                let responseStat = this.handleResponse(data.header)

                // Do some stuff
                this.saveJwt(data.id_token);

                // do call back to original component and pass the response status
                done(responseStat);
            },
            err => this.logError(err)
        );
}

handleResponse(header) {
    if(header.status != 401) {
        return 'success'
    } 

    return 'error blah blah'
}

Хорошо ли в этом случае обратный вызов или лучше справиться с наблюдаемым или обещанием?

В заключение я спрашиваю, что ... Как лучше обрабатывать ответ от ответа http и обрабатывать статус в представлении формы из user.service.ts обратно в login-form.component.ts

Автор: Nige Источник Размещён: 26.11.2015 03:09

Ответы (3)


87 плюса

25264 Репутация автора

Решение

Обновление альфа 47

Начиная с альфа-47 приведенный ниже ответ (для альфа-46 и ниже) больше не требуется. Теперь модуль Http автоматически обрабатывает возвращенные ошибки. Так что теперь так просто, как следует

http
  .get('Some Url')
  .map(res => res.json())
  .subscribe(
    (data) => this.data = data,
    (err) => this.error = err); // Reach here if fails

Альфа 46 и ниже

Вы можете обработать ответ в map(...), перед subscribe.

http
  .get('Some Url')
  .map(res => {
    // If request fails, throw an Error that will be caught
    if(res.status < 200 || res.status >= 300) {
      throw new Error('This request has failed ' + res.status);
    } 
    // If everything went fine, return the response
    else {
      return res.json();
    }
  })
  .subscribe(
    (data) => this.data = data, // Reach here if res.status >= 200 && <= 299
    (err) => this.error = err); // Reach here if fails

Вот plnkr с простым примером.

Обратите внимание, что в следующем выпуске это не будет необходимо, поскольку все коды состояния ниже 200 и выше 299 автоматически выдадут ошибку, поэтому вам не придется проверять их самостоятельно. Проверьте этот коммит для получения дополнительной информации.

Автор: Eric Martinez Размещён: 26.11.2015 03:37

11 плюса

11554 Репутация автора

в angular2 2.1.1 Я не смог поймать исключение, используя шаблон (data), (error), поэтому я реализовал его с помощью .catch (...).

Это хорошо, потому что его можно использовать со всеми другими связанными методами Observable, такими как .retry .map и т. Д.

import {Observable} from 'rxjs/Rx';


  Http
  .put(...)
  .catch(err =>  { 
     notify('UI error handling');
     return Observable.throw(err); // observable needs to be returned or exception raised
  })
  .subscribe(data => ...) // handle success

из документации :

Возвращает

(Наблюдаемый): наблюдаемая последовательность, содержащая элементы из последовательных исходных последовательностей, пока исходная последовательность не завершится успешно.

Автор: Sonic Soul Размещён: 22.11.2016 10:50

4 плюса

489 Репутация автора

Обслуживание :

import 'rxjs/add/operator/map';

import { Http } from '@angular/http';
import { Observable } from "rxjs/Rx"
import { Injectable } from '@angular/core';

@Injectable()
export class ItemService {
  private api = "your_api_url";

  constructor(private http: Http) {

  }

  toSaveItem(item) {
    return new Promise((resolve, reject) => {
      this.http
        .post(this.api + '/items', { item: item })
        .map(res => res.json())
        // This catch is very powerfull, it can catch all errors
        .catch((err: Response) => {
          // The err.statusText is empty if server down (err.type === 3)
          console.log((err.statusText || "Can't join the server."));
          // Really usefull. The app can't catch this in "(err)" closure
          reject((err.statusText || "Can't join the server."));
          // This return is required to compile but unuseable in your app
          return Observable.throw(err);
        })
        // The (err) => {} param on subscribe can't catch server down error so I keep only the catch
        .subscribe(data => { resolve(data) })
    })
  }
}

В приложении:

this.itemService.toSaveItem(item).then(
  (res) => { console.log('success', res) },
  (err) => { console.log('error', err) }
)
Автор: bArraxas Размещён: 20.08.2017 12:20
Вопросы из категории :
32x32