angular - Angular2 Vänta på HttpPost-svar


Jag har en Angular2-applikation i TypeScript. Jag gör en HTTP Post-begäran för att skapa en post. Denna post-begäran fungerar bra och posten sparas, men jag returnerar den nya posten från tjänsten och jag vill lägga till den i en lista i min komponent och uppdatera DOM med den nyligen skapade posten. Men det verkar aldrig returnera i tid, finns det ett accepterat sätt att stoppa bearbetningen tills den returnerar eller upptäcka förändringar i min array och sedan uppdatera DOM?

Min tjänstmetod är som följer:

public AddComment = (comment: RepackComment): Observable<RepackComment> => {
    var json = JSON.stringify({ comment : comment.Comment, rr_id : comment.RepackId, comment_by : comment.CommentBy });
    return this.http.post(this.commentUrl + 'Add', json, {headers: this.headers})
                    .map((response: Response) => <RepackComment>response.json())
                    .catch(this.handleError);
}

Och detta är min komponentmetod:

saveComment(): void{
    console.log(this.newComment);
    this.repackService.AddComment(this.newComment)
                    .subscribe((data: RepackComment) => this.addedComment = data,
                    error => console.log(error),
                    () => console.log('Finished creating new comment'));

    console.log("added Comment: " + this.addedComment);
    this.comments.push(this.addedComment);
    this.addNewComment = false;
}

Så när this.addedComment har fyllts med returvärdet vill jag lägga till det i this.comments-arrayen. Jag sätter sedan en flagga som kallas this.addNewComment som växlar mellan inmatnings- och visningsfält på front-end för att visa datan.

Tack i förväg!!!

REDIGERA

Som begärt här är den lämpliga delen av min mall för dessa kommentarer. Jag använder PrimeNG för mina komponenter:

<p-dataList [value]="comments" [hidden]="addNewComment">
       <header style="height:30px;">
            <button pButton type="button" label="Add Comment" (click)="addComment()" class="actionBtn" style="float:left;width:150px;"></button>
            <span style="margin-left:-105px;font-size:20px;">Comments</span>
       </header>
       <template let-comment>
            <div class="ui-grid ui-grid-responsive ui-fluid" style="font-size:16px;padding:20px;border-bottom:1px solid #D5D5D5;" >
                 <div class="ui-grid-row">
                      <div class="ui-grid-col-12">
                           <div class="ui-grid ui-grid-responsive ui-fluid comment">
                                <div class="ui-grid-row row-div">
                                   <div class="ui-grid-col-3 labelFor">ID: </div>
                                   <div class="ui-grid-col-7 displayFor">{{comment.ID}}</div>
                                </div>
                                <div class="ui-grid-row row-div">
                                   <div class="ui-grid-col-3 labelFor">Comment: </div>
                                   <div class="ui-grid-col-7 displayFor">{{comment.Comment}}</div>
                                </div>
                                <div class="ui-grid-row row-div">
                                   <div class="ui-grid-col-3 labelFor">Author: </div>
                                   <div class="ui-grid-col-7 displayFor">{{comment.CommentBy}}</div>
                                </div>
                             </div>
                         </div>
                     </div>
                  </div>
               </template>
           </p-dataList>
/*INPUT COMPONENTS*/
           <div class="ui-grid ui-grid-responsive ui-fluid" style="font-size:16px;padding:20px;border-bottom:1px solid #D5D5D5;" [hidden]="!addNewComment">
                        <div class="ui-grid-row">
                            <div class="ui-grid-col-12">
                                <div class="ui-grid ui-grid-responsive ui-fluid comment">
                                    <div class="ui-grid-row row-div">
                                        <div class="ui-grid-col-3 labelFor">Comment: </div>
                                        <input type="text" pInputText [(ngModel)]="newComment.Comment" class="displayFor"/>
                                    </div>
                                    <div class="ui-grid-row row-div">
                                        <div class="ui-grid-col-3 labelFor">Author: </div>
                                        <input type="text" pInputText [(ngModel)]="newComment.CommentBy" class="displayFor"/>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <br/>
                        <div class="div-row" style="margin-left:40%;">
                            <button pButton type="button" label="Cancel" (click)="cancelComment()" class="actionBtn" style="width:150px;"></button>
                            <button pButton type="button" label="Save" (click)="saveComment()" class="actionBtn" style="width:150px;"></button>
                        </div>
                    </div>

Svar #1

Som du märkte: Observables fungerar asynkront - så allt efter ditt .subscribe-anrop körs förmodligen innan koden inuti .subscribe-callbacken.

För att åtgärda det behöver du sätta koden, som beror på resultaten av subscribe-anropet, i dess callback:

saveComment(): void{
    console.log(this.newComment);
    this.repackService.AddComment(this.newComment)
                    .subscribe((data: RepackComment) => {
                        this.addedComment = data;

                        // add your code here
                        console.log("added Comment: " + this.addedComment);
                        this.comments.push(this.addedComment);
                        this.addNewComment = false;
                    },
                    error => console.log(error),
                    () => console.log('Finished creating new comment'));
}

Även objektet du får tillbaka från ditt postanrop matchar inte din mall. Jag skulle föreslå denna ändring i ditt AddComment-anrop med RepackComment som har en sådan konstruktor:

public AddComment = (comment: RepackComment): Observable<RepackComment> => {
    var json = JSON.stringify({ comment : comment.Comment, rr_id : comment.RepackId, comment_by : comment.CommentBy });
    return this.http.post(this.commentUrl + 'Add', json, {headers: this.headers})
                    .map((response: Response) => response.json())
                    .map(res => new RepackComment(res.id, res.comment, res.comment_by))
                    .catch(this.handleError);
}