Я использую Ionic2 Storage для хранения учетных данных пользователя access_token, когда пользователь входит в систему.
Когда пользователь пытается получить доступ к backend api, мне нужно предоставить access_token клиенту REST.
Я создал службу, используя https://github.com/hboylan/ng2-http Первоначально пакет использует
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})
}
Сейчас, когда я звоню
@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 })
}
}
Это похоже на то, что я НЕ МОГУ установить пользователя в конструкторе класса CategoryService. Поэтому мне нужно сначала получить пользователя из хранилища, использовать «сеттер» в службе категорий, а затем вложить вызов getAvailableCategories () в функцию getUser (). Then ().
Это потому, что функция getCategories вызывается до того, как конструктор CategoryService завершит настройку пользователя из UserStorage.
Я знаю, что это потому, что вызов является асинхронным, но мне кажется, что использование чего-то вроде setTimeout для «ожидания», пока вызов getUser не вернется, является хакерским и не на 100% надежным.
Есть еще что-нибудь, что я могу попробовать? Я бы очень хотел просто позвонить
this.categoryService.getAvailableCategories().then()
и продолжить оттуда без вложенных вызовов обещаний.
Я готов внести любые разумные изменения, которые сразу же сделают access_token доступным.
then(...)
означает асинхронный. Вероятно, это просто вопрос времени. Значение еще не доступно, когда вы к нему обращаетесь. Вам необходимо правильно связать все асинхронные вызовы, чтобы получать уведомления (ваш переданный обратный вызов вызывается), когда значение становится доступным. - person Günter Zöchbauer   schedule 13.02.2017