2017-02-13 143 views
0

我使用Ionic2存儲來存儲用戶的access_token憑證的服務初始化注射變量,當用戶登錄。如何使用

當用戶試圖訪問一個後端API,我需要到的access_token提供一個REST客戶。

我創建使用hBoylan's ng2-http package 最初的包使用

export class CategoryService extends RESTClient{ 
    categoryList : Category[] = []; 
    public user:User; 
    constructor(protected http:Http) {super(http)} 
} 

我已經使用Angular2 DI到UserStorage組件添加到製作服務:

let categoryServiceFactory = (http:Http, userStorage:UserStorage) => { 
    return new CategoryService(http, userStorage); 
} 
export let categoryServiceProvider = 
{ 
    provide: CategoryService, 
    useFactory: categoryServiceFactory, 
    deps: [Http, UserStorage] 
} 

得到這個:

export class CategoryService extends RESTClient{ 
    categoryList : Category[] = []; 
    public user:User; 
    constructor(protected http: Http, protected userStorage: UserStorage) 
{ 
    super(http); 
    this.userStorage.getUser().then((data:User) => {this.user = data}) 
} 

Cur rently當我打電話

@GET('/itemtype/list') 
@Produces<String>() 
public getAvailableCategories(): Observable<String> { 
    return null; 
} 

我需要使用

protected requestInterceptor(req: Request) { 
    req.headers.set('Authorization', `Bearer ${this.user.api_credentials.access_token}`) 
    return req; 
} 

添加ACCESS_TOKEN憑證

因爲現在我的電話在我的頁面組件已經看起來像這樣:

@Component({ 
    selector: 'page-categories', 
    templateUrl: 'categories.html', 
    providers: [User] 
}) 
export class CategoriesPage implements OnInit { 
    // list of categories 
    public categories: any; 

constructor(public nav: NavController, 
public categoryService: CategoryService, 
public userStorage: UserStorage, 
public user: User) {} 

ngOnInit() { 
    this.userStorage.getUser().then((user: User) => { 
    this.user = user 
    this.categoryService.setUser(this.user); 
    this.categoryService.getAvailableCategories().subscribe(
     (data) => { console.log(data) }, 
     error => console.log(error), 
    () => { }); 
    }); 
} 

// view category 
viewCategory(categoryId) { 
    this.nav.push(CategoryPage, { id: categoryId }); 
} 

showChildren(category: Category) { 
    category.open = !category.open; 
} 

openCategoryPage($event, category: Category) { 
    $event.stopPropagation(); 
    this.nav.push(CategoryPage, { cat_id: category.id }) 
} 

} 

它看起來像這樣的原因是因爲我似乎無法將用戶設置在C的構造函數中ategoryService類。所以我必須先從存儲中獲取用戶,在類別服務中使用「setter」,然後在getUser()。then()函數內部嵌套getAvailableCategories()調用。

這是因爲在CategoryService構造函數完成從UserStorage中設置用戶之前調用了getCategories函數。

我知道這是因爲調用是異步的,但我覺得像使用setTimeout等「等」,直到getUser調用返回是hacky而不是100%可靠。

還有什麼我可以嘗試嗎?我真的很想致電

this.categoryService.getAvailableCategories().then() 

並且從那裏繼續沒有嵌套承諾的電話。

我正在做出任何精明的改變,使access_token馬上可用。

+0

'然後(...)'意味着異步。這可能只是一個時間問題。該值在您訪問時尚不可用。您需要正確鏈接所有異步調用,以便在值可用時獲得「通知」(您傳遞的回調被調用)。 –

+0

你能展示更多的代碼嗎?頁面組件是怎樣的? –

+1

@MichałMiszczyszyn我在問題中添加了整個組件。 – Schwoebel

回答

0

如果getUser調用是異步的,你可以嘗試使它同步:)

如果這不是一個選擇,有一個語法糖,這將有助於你應對一個更好的方式異步調用 - async/await

async ngOnInit() { 
    this.categories = this.categoryService.getCategories(); 
    this.user = await this.userStorage.getUser(); 
    this.categoryService.setUser(this.user); 
    this.categoryService.getAvailableCategories().subscribe(
     (data) => { console.log(data) }, 
     (error) => { console.log(error) }, 
     () => { } 
    ); 
} 

記住,這是async ngOnInit然後await this.userStorage.getUser()

+0

我喜歡這個想法,它解決了我的嵌套問題,但我正在尋找在CategoryService中使用的東西,所以我不必調用categoryService.setUser()。我想幫忙找出解決方案,以便在Angular載入頁面時,CategoryServices的用戶變量將在後臺準備就緒。 – Schwoebel

+0

@Schwoebel完全可以在純TypeScript/JavaScript中做到這一點。只是'hBoylan的ng2-http package'裝飾器顯然不允許異步參數。你應該在GitHub上打開一個問題。 –

+0

@Schwoebel我的回答對你有幫助嗎? –