Заставьте функцию возвращать значение только после завершения HTTP-запроса Angular - PullRequest
0 голосов
/ 30 апреля 2020

Здравствуйте, я создаю angular asyn c валидатор, который должен ждать ответа от HttpRequest от службы.

Мне нужна функция для возврата наблюдаемой информации, возвращаемой вызов http.

Если попробуйте разные коды:

1 - Это не работает, потому что a не определено, потому что httprequest не завершился, когда функция вернула a.

searchValue(controlName, controlValue){
   this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a 
   HTTPrequest and make a subject emit a value.
   let a
   this.cts.dataGetByParamSubject.subscribe(res=>{
   a=(res)
})
return of(a)
}

2 - не работает, потому что не возвращает никакого значения.

searchValue(controlName, controlValue){
       this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a 
       HTTPrequest and make a subject emit a value.
       let a
       this.cts.dataGetByParamSubject.subscribe(res=>{
       a=(res)
       return of(a)
    })
    }

3 - возвращает подписку, а не наблюдаемую.

searchValue(controlName, controlValue){
           this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a 
           HTTPrequest and make a subject emit a value.
           let a
           return this.cts.dataGetByParamSubject.subscribe(res=>{
           a=(res)
           return of(a)
        })
        }

4 - Возвращает заметное, что когда вы отображаете его, res является подписчиком, и я потерялся.

searchValue(controlName, controlValue){
           this.cts.getByParam(controlName, controlValue) // Call a function on the service that make a 
           HTTPrequest and make a subject emit a value.
           let a
           return of(this.cts.dataGetByParamSubject.subscribe(res=>{
           a=(res)
           return of(a)
        })
        })

Служебная сторона:

getByParam(property, value): Observable<HttpResponses> { 
    let data
    let params = new HttpParams()
    .set('schema', this.tipoConfiguracion.codigo)
    .set('property', property)
    .set('value', value)
      this.http.get<HttpResponses>(this.apiUrl + 'validation', {params: params}).subscribe(res=>{
        this.dataGetByParamSubject.next({message: res.message, data: res.data, error: res.error})
     })
     return
  }

Как я могу это сделать Работа? Спасибо за вашу помощь.

1 Ответ

2 голосов
/ 30 апреля 2020

[ОБНОВЛЕНИЕ]: Я сделал несколько изданий для комментариев.

searchValue(controlName, controlValue) {
  // you don't need dataGetByParamSubject as it emits an object with the same
  // shape of the returning of this.cts.getByParam
  return this.cts.getByParam(controlName, controlValue);
}

Обратите внимание, что, поскольку у вас есть только одна заметка, на которую нужно подписаться после получения возврата из getByParam, вы также могли бы использовать mergeMap или concatMap без различия.

Также обратите внимание на оператор take(1) в конце цепочки труб. Я добавил его, потому что похоже, что this.cts.dataGetByParamSubject - это долгоживущий поток, и вы просто хотите получить одно значение, верно?

Вы можете многое узнать об операторах на https://www.learnrxjs.io.

На сервисе вы должны сделать:

getByParam(property, value): Observable<HttpResponses> { 
  let data
  let params = new HttpParams()
      .set('schema', this.tipoConfiguracion.codigo)
      .set('property', property)
      .set('value', value);

  // there's no point in the dataGetByParamSubject here, as you will use 
  // it directly in your component.
  return this.http.get<HttpResponses>(this.apiUrl + 'validation', {params: params}).pipe(
    map((res: any) => ({
      message: res.message, 
      data: res.data, 
      error: res.error
    })
  ));
}
...