2017-02-15 16 views
9

Мне нужно вызвать метод после того, как получить данные из запроса HTTP POSTУгловое 2: Как вызвать функцию после того, как получить ответ от подписки http.post

услуги: request.service.TS

get_categories(number){ 
this.http.post(url, body, {headers: headers, withCredentials:true}) 
    .subscribe( 
     response => { 
     this.total = response.json(); 

     }, error => { 
    } 
); 

} 

компонент: categories.TS

search_categories() { 

this.get_categories(1); 
//I need to call a Method here after get the data from response.json() !! e.g.: send_catagories(); 
} 

работает только если я изменяю:

услуги: request.service.TS

get_categories(number){ 
this.http.post(url, body, {headers: headers, withCredentials:true}) 
    .subscribe( 
     response => { 
     this.total = response.json(); 
     this.send_catagories(); //here works fine 

     }, error => { 
    } 
); 

} 

Но мне нужно вызвать метод send_catagories() внутри компонента после вызова this.get_categories(1); как этот

компонента: categories.TS

search_categories() { 

this.get_categories(1); 
this.send_catagories(response); 
} 

Что я делаю неправильно?

+0

Является ли 'send_catagories()' также используемым наблюдаемым? Если да, вам нужно связать наблюдаемый из get_categories() с адресом в send_categories() с помощью оператора '.mergeMap()'. Дайте мне знать, если вам нужна помощь в синтаксисе. – AngularChef

+0

send_catagories() не использует наблюдаемые, пожалуйста, покажите мне синтаксис: return this.http.post (url, body, {headers: headers, withCredentials: true}) .subscribe ( response => {this.total_page = response .json(); return this.total_page; }, .share() ); } then this.get_category (1) .subscribe (response => { this.callfunc(); }); – Louis

+0

Понял. Я отправил ответ с правильным синтаксисом. – AngularChef

ответ

15

Обновление ваш метод get_categories() до r eturn общее (завернутые в наблюдаемой):

// Note that .subscribe() is gone and I've added a return. 
get_categories(number) { 
    return this.http.post(url, body, {headers: headers, withCredentials:true}) 
    .map(response => response.json()); 
} 

В search_categories(), вы можете подписаться на наблюдаемый возвращаемый get_categories() (или вы могли бы сохранить преобразуя его, приковав больше RxJS операторов):

// send_categories() is now called after get_categories(). 
search_categories() { 
    this.get_categories(1) 
    // The .subscribe() method accepts 3 callbacks 
    .subscribe(
     // The 1st callback handles the data emitted by the observable. 
     // In your case, it's the JSON data extracted from the response. 
     // That's where you'll find your total property. 
     (jsonData) => { 
     this.send_categories(jsonData.total); 
     }, 
     // The 2nd callback handles errors. 
     (err) => console.error(err), 
     // The 3rd callback handles the "complete" event. 
    () => console.log("observable complete") 
    ); 
} 

Обратите внимание, что вы подписывайтесь только по номеру, в конце.

Как я уже говорил в комментариях .subscribe() метод любой наблюдаемой принимает 3 обратных вызовов, как это:

obs.subscribe(
    nextCallback, 
    errorCallback, 
    completeCallback 
); 

Они должны быть приняты в этом порядке. Вам не нужно проходить все три. Много раз nextCallback реализуется только:

obs.subscribe(nextCallback); 
+0

Спасибо, спасибо, спасибо! он работает идеально! только два вопроса: 1) внутри this.send_categories (всего) {this.myNewTotal = total} Как я могу выделить данные (responsee.json) из «общего» параметра? 2) я добавил «ошибку» к синтаксису: .map (response => response.json()), error => { }); если мне нужно вызвать this.send_categories (всего) только в случае ошибки, как я могу подписаться на ошибку? – Louis

+0

Хм. Основываясь на вашем предыдущем коде, я думал: 'response.json()' ** WAS ** сумма. Я имею в виду, что я назвал переменную 'total', но она содержит все, что находится в' response.json() '; вы можете назвать эту переменную так, как хотите. Я обновил свой ответ, чтобы лучше отразить это, а также показать вам, как обрабатывать ошибку. – AngularChef

+0

Возможно, мне не хватает точки третьего аргумента в подписке, но мне интересно, можете ли вы вызвать метод для завершения обратного вызова? – Winnemucca

3

Вы можете добавить функцию обратного вызова в свой список параметров get_category (...).

Ex:

get_categories(number, callback){ 
this.http.post(url, body, {headers: headers, withCredentials:true}) 
    .subscribe( 
     response => { 
     this.total = response.json(); 
     callback(); 

     }, error => { 
    } 
); 

} 

И тогда вы можете просто позвонить get_category (...), как это:

this.get_category(1, name_of_function); 
+0

Спасибо, я попробую. Но моя идея - использовать что-то более профессиональное, чтобы поймать ответ. Например: get_category (1). Then или наблюдаемый, но я не знаю, как это сделать. – Louis

+0

. Нет ничего непрофессионального в использовании функций обратного вызова, но подходит вам – Gab

+2

На мой взгляд, передача обратного вызова службе при использовании наблюдаемых не является хорошим шаблоном , Как упоминал Луис, это делает дополнительную логику и обработку ошибок уродливыми. – RobM

1
get_categories(number){ 
return this.http.post(url, body, {headers: headers, withCredentials:true}) 
     .map(t=> { 
      this.total = t.json(); 
      return total; 
     }).share(); 
);  
} 

затем

this.get_category(1).subscribe(t=> { 
     this.callfunc(); 
}); 
+0

Да, это то, что я хочу, как я могу сохранить старый синтаксис без «.map» ?, например: return this.http.post (url, body, {headers: headers, withCredentials: true}) .subscribe ( Ответ => { this.total = response.json(); итоговый итог; }). Share(); – Louis

+0

(173,69): ошибка TS2339: свойство 'subscribe' не существует в типе 'Subscription'. – Louis

+0

Зачем вам оригинальный синтаксис? FRP - это объединение потоков для создания одного значимого наблюдаемого, на который можно подписаться. – pixelbits

0

Вы можете закодировать как лямбда-выражения в качестве третьего параметра (по полной) методу подписки. Здесь я повторно устанавливаю переменную departmentModel в значения по умолчанию.

saveData(data:DepartmentModel){ 
    return this.ds.sendDepartmentOnSubmit(data). 
    subscribe(response=>this.status=response, 
    ()=>{}, 
    ()=>this.departmentModel={DepartmentId:0}); 
}