Angular - получить и вернуть наблюдаемый <T>ответ в Http.post - PullRequest
0 голосов
/ 09 января 2019

Я реализовал метод, который возвращает Observable. Внутри этого метода я использую http.post для отправки запроса на серверную часть. После получения ответа, который является объектом JSON, я хочу сохранить его в переменной Observable и вернуть эту переменную. Но почему-то мне не удалось решить эту проблему. В .subscribe переменная res не хранится в переменной postResponse, но я вижу в "local" console.log, что переменная res имеет правильное значение. Глобальный console.log пуст. Кроме того, я получаю ошибку:

"TS2322: Тип «ArqResponse» не может быть назначен для типа «Наблюдаемый»» ошибка для возврата.

Мой код выглядит так:

postARQRequest(request): Observable<ArqResponse>{
    let postResponse = new ArqResponse;
    const result = this.http.post<ArqResponse>(this.arqUrl, request)
                       .subscribe((res: ArqResponse) => { postResponse = res; console.log('shadow: ' + res)});
    console.log('global: ' + JSON.stringify(postResponse));
    return postResponse;
}

Мои вопросы:

  1. Как я могу сохранить тело ответа в переменной, которая затем может быть возвращенным?
  2. Как я могу "привести" переменную ArqResponse к Наблюдаемая переменная?
  3. .subscribe, кажется, неправильно, так как я получаю:

this.arqService.postARQRequest (...). Подписка не является функцией Ошибка

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Полагаю, это то, что вы хотите:

postARQRequest(request): Observable<ArqResponse>{
    return this.http.post<ArqResponse>(this.arqUrl, request);
}

Нет необходимости подписываться на что-либо здесь. Учитывая, что this.http.post возвращает желаемый тип, просто верните его.

Если вы действительно хотите сохранить ответ в локальной переменной, есть несколько способов сделать это:

Используйте обещание вместо этого, чтобы получить результат. Сделайте это наблюдаемым, используя of позже:

async postARQRequest(request): Observable<ArqResponse>{
    let postResponse = new ArqResponse;
    postResponse = await this.http.post<ArqResponse>(this.arqUrl, request).toPromise();

    return of(postResponse);
}

Используйте оператор tap, чтобы реагировать на ответ, но не изменять его

postARQRequest(request): Observable<ArqResponse>{
    return this.http.post<ArqResponse>(this.arqUrl, request).pipe(
        tap((res) => ...) // do stuff with res here, but it won't be mutated
    );
}

Используйте оператор map, чтобы сопоставить ответ с чем-то другим

postARQRequest(request): Observable<ArqResponse>{
    return this.http.post<ArqResponse>(this.arqUrl, request).pipe(
        map((res) => ...) // do stuff with res here, but it *will map to whatever you return from this handler*
   );
}
0 голосов
/ 09 января 2019

Я думаю, что это может помочь вам

postARQRequest(): Observable<ArqResponse[]> {
 return this.http.post(this.arqUrl, request)
 .map(this.extractData()) <== passing result of function
 .catch(this.handleError()); <== passing result of function
}

обрабатывать ответ и ошибку здесь

private extractData(res: Response) {
   let body = res.json(); 
   return body.data || { }; 
}

private handleError (error: any) {
    let errMsg = error.message || 'Server error';
    console.error(errMsg); 
    return Observable.throw(errMsg);
}
0 голосов
/ 09 января 2019

YМетод http.post уже возвращает Observable, так что вы можете сделать это напрямую:

postARQRequest(request): Observable<ArqResponse>{
    return this.http.post<ArqResponse>(this.arqUrl, request);
}

и подписаться на него: this.arqService.postARQRequest(...).subscribe()

Если вы хотите преобразовать объект в Observable, вы можете использовать of из Rxjs6 :

import { of } from 'rxjs';

// ...

// create an Observable from a value:
of(someObject);
...