2016-11-30 6 views
2

Я пытаюсь создать пользовательский запрос с угловым 2 http, расширив значение по умолчанию, и я использую локальное хранилище Ionic 2 для хранения токена аутентификации. (Скорее всего, в будущем будет использовать файловую систему). Моя проблема заключается в том, как вернуть разрешенное обещание из моей службы http, чтобы я мог подписаться на Observable в моем компоненте. Я пробовал Observable.fromPromise и другие варианты безрезультатно.Возвращение разрешено, наблюдаемое изнутри обещания

request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> { 

    // Get the token used for this request. 
    // * Need to return this promise resolved. 
    var promise = this.storage.get('token').then(token => { 

    if (typeof url === 'string') { // meaning we have to add the token to the options, not in url 
     if (!options) { 
     // let's make option object 
     options = {headers: new Headers()}; 
     } 
     options.headers.set('Authorization', 'Basic ' + token); 
    } else { 
    // we have to add the token to the url object 
     url.headers.set('Authorization', 'Basic ' + token); 
    } 

    return super.request(url, options).catch(this.catchAuthError(this)); 

    }).catch(error => { 
    console.log(error); 
    }); 

} 

Идея основана на этом сообщении в блоге, но ионное хранилище возвращает обещание. http://www.adonespitogo.com/articles/angular-2-extending-http-provider/

+0

Кто такой 'пользователь'? –

+0

Должен был быть токеном. –

+1

Невозможно иметь дело с наблюдаемыми внутри 'then'. Я думаю, что это должно быть что-то вроде «return Observable.fromPromise (this.storage.get ('token')). ​​Map (token => {...; return url}). MergeMap (url => super.request (. ..)) ' – estus

ответ

6

Я не знаю, если это хранение возвращает обещание, которое совместимо с Rx, но если это то решение должно выглядеть следующим образом:

request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> { 

    return Observable 
     .fromPromise(this.storage.get('token')) 
     .flatMap(token => { 

      if (typeof url === 'string') { // meaning we have to add the token to the options, not in url 
       if (!options) { 
        // let's make option object 
        options = {headers: new Headers()}; 
       } 
       options.headers.set('Authorization', 'Basic ' + token); 
      } else { 
       // we have to add the token to the url object 
       url.headers.set('Authorization', 'Basic ' + token); 
      } 

      return super.request(url, options).catch(this.catchAuthError(this)); 

     }); 
    }); 

} 

Если обещание не совместим с наблюдаемыми есть еще способ сделать это, хотя это не так элегантно:

request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> { 

    return Observable.create((observer: Observer) => { 

     this.storage.get('token').then(token => { 

      if (typeof url === 'string') { // meaning we have to add the token to the options, not in url 
       if (!options) { 
        // let's make option object 
        options = {headers: new Headers()}; 
       } 
       options.headers.set('Authorization', 'Basic ' + token); 
      } else { 
       // we have to add the token to the url object 
       url.headers.set('Authorization', 'Basic ' + token); 
      } 

      super.request(url, options).catch(this.catchAuthError(this)).subscribe(result => { 
       observer.next(result); 
       observer.complete(); 
      }); 

     }).catch(error => { 
      observer.error(error); 
     }); 

    }); 

} 
+0

Первый вариант работал, спасибо !. Раньше я не использовал плоскую карту. Также необходимо добавить импорт «rxjs/add/operator/mergemap»; чтобы получить плоскую карту для работы. –

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