2016-10-10 2 views
1

Update:

я продлить Http класса, когда я deleteDocument() я хочу обрабатывать ошибки затем getTicket() затем повторите запрос ма deleteDocument() с новым this.TICKET:получить новый билет затем повторите первый запрос

@Injectable() 
export class HttpService extends Http { 
    public SERVER_URL: string = 'http://10.0.0.183:8080/alfresco/s/' 
    public TICKET: string = '' 

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) { 
     super(backend, defaultOptions); 
    } 


    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> { 
     return this.intercept(super.post(url,body, options)); 
    } 

    intercept(observable: Observable<Response>): Observable<Response> { 
     return observable.catch(initialError => { 
      if (initialError.status === 401) { 
       return this.getTicket() 
        .do(res => { 
         // HERE I WANT RETRY MY FIRST REQUEST 
         this.TICKET = res.json().data.ticket 
        }) 
      } else { 
       return Observable.throw(initialError); 
      } 
     }) 
    } 

    getTicket() { 
     return this.post(this.SERVER_URL + 'api/login', JSON.stringify({username: 'admin', password: 'admin'})) 
    } 


    deleteDocument(idFile: number) { 
     return this.post(this.SERVER_URL + 'dms/file/delfile?idfile=' + idFile + '&alf_ticket=' + this.TICKET, {}).map((data: Response) => data.json()) 
    } 
} 

После получить мой новый билет, я хочу повторить свой первый запрос с новым URL-адресом. Благодаря

+0

Можете ли вы добавить код, где вы на самом деле на запрос? Ваш метод повторения будет новым вызовом метода запроса, поэтому нам нужно знать его подпись. – Supamiu

+0

пожалуйста, извините, вот вы (см. Обновление) – istiti

ответ

0

Я не знаю, есть ли более простой способ, но я хотел бы использовать concatMap() оператор и рекурсивный вызов deleteDocument() с идентификатором, возвращенным из предыдущего вызова:

Это должно имитировать ситуацию:

import {Observable} from 'rxjs'; 

function deleteDocument(willFail: bool, id) { 
    return Observable.of("I'm your response: " + id) 
    // process response and eventualy throw error 
    .concatMap(val => { 
     if (willFail) { 
     return Observable.throw({response: val, message: "It's broken"}); 
     } else { 
     return Observable.of(val); 
     } 
    }) 
    // recover from the error 
    .catch(initialError => { 
     return deleteDocument(false, initialError.response.length); 
    }); 
} 

deleteDocument(true, 42).subscribe(result => console.log(result)); 

Смотреть демо: http://plnkr.co/edit/rUbLgEwtw7lSBueKJ5HN?p=preview

Это выводит на консоль:

I'm your response: 21 

Я имитирую ошибку с аргументом willFail. Оператор concatMap сервер здесь, чтобы различать ошибку и правильный ответ. Я также перехожу по оригиналу id и к некоторой обработке только для демонстрационных целей.

В вашем случае, вы бы добавить к intercept() также все параметры, необходимые для восстановления оригинального запроса HTTP и вместо this.getTicket().do() использования:

return this.getTicket().concatMap(response => { 
    var newBody = {id: response.ticketId}; 
    return this.post(originalUrl, newBody, ...); 
}); 

Оператор do() в основном используется только отлаживать, что происходит в вашем цепи оператора, он никоим образом не изменяет цепочку.

Я не знаю, что на самом деле делает ваш код, но я надеюсь, что это имеет смысл для вас.

Возможно подобный вопрос к твоему: Observable Continue calling API and changing parameters based on condition

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