2017-03-06 48 views
0

我想在nodejs中使用expressjs和angular 2來執行回調函數(我不知道它是否與angular2部分相關)。如何處理nodejs中的Promise

我的工作是: 我在angular2中有一個formular,我發送一個get請求到我的API路由,然後我通過get發送公式中的文本字段到URL,然後我做一個MYSQL查詢查看電話簿數據庫,我期望從電話簿中獲得完整用戶的詳細信息。

表現公式:

<div class="container"> 
<div class="col-md-4"> 
<h1>Addressbook</h1> 
<form [formGroup]="searchForm" (ngSubmit)="doSearch($event)"> 
<input formControlName="searchString" type="text" placeholder="Name"> 
<button type="submit">Search</button> 
</form> 
</div> 
</div> 

第一功能,doSearch:

doSearch(event) { 
    let formData = this.searchForm.value; 
    var searchString = this.searchForm.value.searchString; 

    this.http.get('/phonebook/search/'+searchString, function(req, res){}).subscribe(
    function(response) { 
    console.log("Success Response"); 
    }, 
    function(error) { console.log("Error happened" + error)}, 
    function() { console.log("the subscription is completed")} 
    ); 
} 

這要求在發送參數的路線,所以不用這麼辛苦。

現在創建路由器進入遊戲:

public static create(router: Router, basePath: string) { 
    console.log("[SearchRoute::create] Creating routes for /search."); 
    // call the function for retrieving the address book results 
    router.get(basePath + "/search/:searchString", (req: Request, res: Response, next: NextFunction) => { 
    console.log("## [SearchRoute] Called GET /search."); 
    var object = searchUser(req); 
    console.log(object); 
     }); 
} 

最後,功能searchUser被調用:

function searchUser(req: Request) { 

    console.log("searchUser Function executed."); 

    var searchString = req.params.searchString; 

    var query = p_query('SELECT XXXX') 
    .then(function (results) { 
    console.log("query executed and all okay"); 
    return (results); 
    }) 
    .catch(function (error) { 
    console.error("Wooopsi", error); 
    }); 

    console.log("query result: "+query); 
} 

此外,我張貼在這裏,我打造成爲新的查詢功能能夠處理承諾(我不知道它是否是最佳選擇):

function p_query(q) { 
    return new Promise(function (resolve, reject) { 
    // The Promise constructor should catch any errors thrown on 
    // this tick. Alternately, try/catch and reject(err) on catch. 
    myMYSQL.db.query(
    q, 
    function (error, results) { 
    if (error) 
    reject(error); 
    resolve(results); 
    }); 
    }) 
}; 

因此,我真正想做什麼,我的問題是什麼?

我想要查詢的結果返回給客戶端(angular2表現公式),我是不是能夠做到這一點......

在此之後很長的帖子所以,我很感激,如果你直到這裏讀完,併爲複雜的問題感到抱歉!

PS:我知道我解釋自己真的不好:(

問候, 丹尼爾

+0

是承諾使用是必要的嗎? –

+0

可能不是在這種情況下,但我有另一種功能的情況下,我需要做一個查詢,取決於第一個查詢的結果(在第一個查詢中,我查找客戶端ID,並使用該客戶端ID在第二個查詢中),當我將它們放在同一個代碼塊中時,它們會同時執行,而第二個查詢失敗(因爲會先執行),所以對於這種情況可能不會,但我真的很想使用它 – DaRo

+0

where是你的例子您的路由器定義中的res.json(object)?然後在您的doSearch中,您必須處理收到的數據,例如response.body? – Myonara

回答

0

在這種official angular 2 documentation on the http client他們提出把HTTP邏輯放到一個單獨的服務客戶端。我設置它類似的例子只是一個search.service。TS:

import { Injectable } from '@angular/core'; 
import { Http, Response,Headers, RequestOptions,URLSearchParams } 
      from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class SearchService { 
    constructor(private http: Http) { 
    } 

    getSearchResult(searchString) : Observable<any> { 
     return this.http.get('/phonebook/search/'+searchString) 
     .map(this.extractData) 
     .catch(this.handleError); 
    } 

    private extractData(res: Response) { 
     let body = res.json(); 
     return body; 
    } 
    private handleError (error: Response | any) { 
     let errMsg: string; 
     if (error instanceof Response) { 
      const body = error.json() || ''; 
      const err = body.error || JSON.stringify(body); 
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 
     } else { 
      errMsg = error.message ? error.message : error.toString(); 
     } 
     return Observable.throw(errMsg); 
    } 
} 

在組件的進口業務,做的代碼片段:

// don't forget to put the service in the app.modul or the component providers! 
    constructur(public mySearchService : SearchService) {} 

// in your doSearch of your component: 
    doSearch(event) { 
    let formData = this.searchForm.value; 
    var searchString = this.searchForm.value.searchString; 
    mySearchService.getSearchResult(searchString).subscribe(
     data => mylist.data, // or which datastructure I want to write to. 
     error => console.error(error) // or how I log the errors.. 
    ); 
    } 

編輯:在你的數據庫模型search_user:

function searchUser(searchString) { 
    console.log("searchUser Function executed."); 
    return myMYSQL.db.select('phonebookentry', { 
     pbe_lastname: searchString, pbe_syncstate: 'new' 
    }) // returning the promise/observable to the main function... 
} // Currently I don't know, how the returned data looks like. 

在節點/快遞方在the router發送res.json編輯:使用異步調用searchUser

router.get(basePath + "/search/:searchString", 
    (req: Request, res: Response, next: NextFunction) => { 
    console.log("## [SearchRoute] Called GET /search."); 
    searchUser(req) 
    .then(data => res.json(data);console.log(data)) 
    .catch (error => console.log(error)); 
    }); 
+0

我爲帖子添加了另一個答案,您幫我一個很多,它只是最後一個失蹤的功能!非常感謝你 – DaRo

+0

第二件事,我發現: 我的組件(角應用程序)和服務(處理搜索的服務)是完全分開的東西,所以進入doSearch導入服務的步驟將不會如此好,因爲mysearchservice它在服務端......我不知道我是否解釋得那麼好 – DaRo

+0

謝謝你的解決方案! – DaRo

0

你應該去遞歸回調每個查詢的結果儘量享受異步平臺的美容 發送數據。通過

res.send(data); 
+0

好吧,這是一個點,我會這樣做。但問題是,我怎麼能發送一個對象回客戶端?這是我錯過的部分 – DaRo

+0

您可以創建一個空變量,並在每次查詢後添加數據,最後您可以通過路由器的響應實例將數據發送到客戶端 –

0

你的答案它是完全完美的,我明白一切!我現在面臨的唯一問題,它的這一個:

我調用函數searchUser,它不返回任何東西,只是一個未定義的對象,所以我quess我沒有做正確的返回。

這是我searchUser功能:

function searchUser(searchString) { 

console.log("searchUser Function executed."); 

myMYSQL.db.select('phonebookentry', { 
pbe_lastname: searchString, 
pbe_syncstate: 'new' 
}).then(function (user) { 
console.log("user before: "+user); 
return (user); 
}).catch(function (err) { 
console.log(err); 
})} 

非常感謝你對你有用的答案!我幾乎在這裏完成

+0

哦,節點的DB端的searchUser也是異步的,今天晚上我會擴展我的答案以涵蓋這個。 – Myonara

+0

非常完美,非常感謝你,如果你需要更多的文件或信息,或者別的什麼,只需要問問。非常感謝您花時間幫助我! – DaRo

+0

我編輯了我的答案並用**編輯**標記。我不知道,數據庫的輸出如何看起來像在/ Catch路徑中。 – Myonara