2017-02-13 148 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我的回答对你有帮助吗? –