2016-05-15 2 views
28

Я столкнулся с странной проблемой, когда служба Http Angular2 (RC1) Http выполняет вызов http.post дважды. Я отлаживал свое приложение, и я знаю, что это не проблема с событием клика. Все вызовы, ведущие на основной вызов службыAngular2 http.post получает исполнение дважды

public create(json: Object, params?: Object): Observable<T> { 
    let body = JSON.stringify([json]); 
    let headers = this.getHeaders(); 
    let options = new RequestOptions({ headers: headers }); 

    return this._http.post(this.createURL(this.getCreateURL(), [], params), body, options) 
    .map(res => this.handleObjectResponse(res)); 
} 

запускаются один раз. Затем, когда я начал отслеживать проблему, я узнал, что мой обработчик this.handleObjectResponse выполняется дважды. Таким образом, я вникал дальше и достиг @angular/http/src/backends/xhr_backend.ts, где они делают это

constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) { 
    this.request = req; 
    this.response = new Observable<Response>((responseObserver: Observer<Response>) => { 
     let _xhr: XMLHttpRequest = browserXHR.build(); 
     _xhr.open(RequestMethod[req.method].toUpperCase(), req.url); 
     // load event handler 
     ... 
     .. 

Так что я поставил точку останова на this.request = req;, а затем другую точку останова на let _xhr: XMLHttpRequest = browserXHR.build();, и я узнал, что я попал в первую контрольную точку один раз, а затем я ударил второй точки останова из обратный вызов дважды.

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

В моем коде я создал несколько абстрактных классов общих сервисов: GenericService и FullService, который расширяет GenericService. Оба эти являются абстрактными и используют generics, а реальные классы обслуживания, которые вводятся в различные компоненты, распространяются либо на GenericService, либо на FullService. Вы, ребята, думаете, что эта установка может быть причиной двойной казни?

Все идеи оценены!

Заранее благодарен!

P.S.

Это не происходит, но это случается и с puts.

+0

Вы можете поделиться кодом звонка? возможно, существует несколько подписей на наблюдаемые, в этом случае 'return this._http.post (this.createURL (this.getCreateURL(), [], params), body, options) .map (res => this.handleObjectResponse (res)). share(); ' должен решить его https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/share.md – teleaziz

+1

Святое дерьмо! Большое вам спасибо, что действительно разрешило это. Теперь мне просто нужно оборачивать голову тем, что я сделал, чтобы вызвать это в первую очередь. Не стесняйтесь публиковать это как ответ, поэтому я могу принять его и снова поблагодарить тонну !!!! – RVP

ответ

53

Служба http возвращает холодный наблюдаемый, который получает executed on every subscribe, вы хотите преобразовать его в горячее наблюдаемое, которое будет выполняться только в первой подписке и использовать одно и то же значение для последующих подписчиков.

Чтобы преобразовать все, что вам нужно сделать, это share это:

return this._http.post(this.createURL(this.getCreateURL(), [], params), body, options) 
.map(res => this.handleObjectResponse(res)) 
.share(); 
+1

Этот комментарий на самом деле помог мне исправить еще одну проблему в последнем RC Angular2. Спасибо чувак. Наблюдения - прекрасная концепция, но немного сложная задача. –

+3

Затем они должны быть заменены нецелым кодом, потому что «сложный» идет назад, что ухудшает ситуацию, и отлично работает –

+3

, поэтому я полагаю, что ALWAYS ставит share() после того, как HTTP-вызов является хорошей практикой, если вы вернете это из метода –

0

Это происходит со мной, потому что я (key.enter)="someSubmitFunction()" на одном из входных полей формы. Когда я нахожусь в поле ввода, форма будет отправляться дважды. По-видимому, это не было необходимо. Когда я удалю это, форма все равно будет отправлена, когда я нажму Enter, но теперь только один раз.

0
its happening because HTTP OPTIONS executed first, and you have to restrict unwanted HTTP method before executing your Logic, always use isset method,see example below 

if(isset($_POST)) 
{ 
    $name = $_POST["name"]; 
    $country = $_POST["country"]; 

    $sql = 'INSERT INTO user values("' . $name . '","' . $country . '")'; 

      if ($conn->query($sql)=== TRUE) 
      { 
       $outp = "Inserted " . $name . " and " . $country; 
       echo json_encode($outp); 
      } else { 
       echo json_encode("Error: " . $sql . "<br>" . $conn->error); 
      } 
     } 


here it will insert row in table only when its POST METHOD. 
Смежные вопросы