2016-12-08 1 views
1

Я использую пакет ionic/storage для хранения api_token для пользователей после их входа в систему, поэтому я могу использовать уникальный токен для взаимодействия с API.Ionic 2 - Получить токен из значения хранилища и задать заголовок перед HTTP-запросом

Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно получить значение через storage.get, который возвращает обещание и результаты в заголовках, которые я хочу установить, не будучи установленными во времени.

Мне нужно вернуть экземпляр RequestOptions, но не могу понять, как добавить заголовок, который я получаю, когда он исходит из обещания. Добавление заголовка, синхронного с localStorage, отлично работает при тестировании, поэтому проблема должна быть выполнена asynch.

createAuthorizationHeader(headers: Headers) { 
    // this does add the header in time 
    localStorage.setItem('api_token', 'some token'); 
    headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token')); 

    // this does not add the header in time 
    return this.storage.get('api_token').then((value) => { 
     headers.append('Authorization', 'Bearer ' + value); 
    }); 
} 

getHeaders(path): RequestOptions { 
    let headers = new Headers({ 
     'Accept': 'application/json', 
     'Content-Type': 'application/json' 
    }); 

    if(!this.isGuestRoute(path)) { 
     this.createAuthorizationHeader(headers); 
    } 

    return new RequestOptions({ headers: headers }); 
} 

get(path: string) { 
    return this._http.get(this.actionUrl + path, this.getHeaders(path)) 
     .map(res => res.json()) 
     .catch(this.handleError); 
} 

Edit: Рабочий код теперь выглядит как этот

getApiToken(): Observable<Headers> { 
    return Observable.fromPromise(this.storage.get('api_token')); 
} 

getHeaders(): Headers { 
    return new Headers({ 
     'Accept': 'application/json', 
     'Content-Type': 'application/json' 
    }); 
} 

get(path: string) { 
    let headers: Headers = this.getHeaders(); 

    if(!this.isGuestRoute(path)) { 
     return this.getApiToken().flatMap(data => { 
      headers.append('Authorization', 'Bearer' + data); 

      return this._http.get(this.actionUrl + path, { headers : headers }) 
       .map(res => res.json()) 
       .catch(this.handleError); 
     }); 
    } 

    return this._http.get(this.actionUrl + path, { headers : headers }) 
     .map(res => res.json()) 
     .catch(this.handleError); 
} 

ответ

7

Отъезд мой Похожая проблема Angular2 - Use value of Observable returning method in another Observable

Если преобразовать обещание в Observable вы сможете использовать rxjs flatMap функция.

Позвольте мне показать вам, что ваш будет несколько выглядеть тогда

getApiToken(): Observable<Headers> { 
    return Observable.fromPromise(this.storage.get('api_token')); 
    //OR return Observalbe.of(this.storage.get('api_token')); 
} 

getHeaders(): Headers { 
    //create all headers here except the 'api_token' 
    ..... 
} 


get(path: string): Observable<any> { 
    let headers: Headers = this.getHeaders(); 
    return this.getApiToken().flatMap(data => { 

     headers.append('Authorization', 'Bearer'+data); 

     return this.http.get(this.actionUrl + path, headers) 
      .map(res => res.json()) 
      .catch(this.handleError); 
    }); 
} 

ИЛИ (Только узнал об этом, чтобы не уверен, если он будет работать)

createAuthorizationHeader(headers: Headers) { 
    // this does add the header in time 
    localStorage.setItem('api_token', 'some token'); 
    headers.append('Authorization', 'Bearer ' + localStorage.getItem('api_token')); 

    // this does not add the header in time 
    let api_token = await this.storage.get('api_token'); 
    headers.append('Authorization', 'Bearer ' + api_token); 
} 
+0

Спасибо, первый работает! Вариант 'await' вызывает ошибку, которая поддерживается только при таргетинге на ES2015 или выше по какой-либо причине. –

0

Я предлагаю смотреть на перехватчики: https://angular.io/guide/http (serach для раздела с названием «Настройка новых заголовков»). Я попытался использовать BaseRequestOptions, но это все еще вызывает проблему async.

Regadring Ivaro18 Ответ, чтобы установить заголовки, когда токен получен и сохранен в хранилище, не будет ли это нарушаться, когда пользователь вернется к приложению/странице после убийства браузера приложения/закрытия? Заголовок установлен в память, поэтому он не будет постоянным.

Смежные вопросы