2016-10-14 3 views
2

У меня есть компонент для входа и простой метод:Угловое 2, Наблюдаемые - вернуть некоторые данные из подписываться

login(event) {  
    event.preventDefault(); 
    this.authService.login(this.user);  
} 

Это мой AuthService:

export class AuthService { 
    constructor(private jsonApiService:JsonApiService) { 
    } 

    isLoggedIn: boolean = false; 

    login(user:User): any { 
     this.jsonApiService.post('/token', user) 
      .subscribe(
       resp => { 
        check if success, 
        store token to localstorage, 
        set isLoggedIn = true 
        * return new object with data about success/error 


       }, 
       err => {  
        handle error 
        * return new object with data about success/error 
       }); 
    } 

    logout(): void { 
     this.isLoggedIn = false; 
    } 
} 

Этот код работает отлично. Я получаю ответ, но мне интересно, как вернуть некоторые данные из службы в компонент. Я не хочу переводить подписку на компонент, потому что, я считаю, обработка должна быть в AuthService.

+0

Вы можете сохранить ваши данные в 'AuthService', а затем запросить данные через GET-метод, который ваш компонент может вызывать. Вы также можете сделать этот метод в качестве наблюдаемого, чтобы ваш компонент подписался на нем. Это позволит 'AuthService' до того, как компонент получит данные. – John

ответ

5

Поскольку запрос HTTP работает асинхр, вы не можете вернуть что-то изнутри лямбда, но вы можете передать обратный вызов, подобный этому (что было бы по существу похоже на подписку):

login(user: User, onSuccess: (data) => void, onError: (data) => void = null): any { 
    this.jsonApiService.post('/token', user) 
     .subscribe(
      resp => { 
       check if success, 
       store token to localstorage, 
       set isLoggedIn = true 

       onSuccess(/*somedata*/); 
      }, 
      err => {  
       handle error 

       if (onError) 
        onError(/*somedata*/); 
      }); 
} 

А потом в компоненте:

login(event) {  
    event.preventDefault(); 
    this.authService.login(this.user, (data) => { 
     // do something here with the data 
    });  

    // or optionally with onError callback 
    this.authService.login(this.user, (data) => { 
     // do something here with the data 
    }, 
    (errData) => { 
     // do something with the error 
    });  
} 
-1

Возможно, вы можете сделать следующее вещь:

// AuthService

export class AuthService { 
    constructor(private jsonApiService:JsonApiService) { 
    } 

    isLoggedIn: boolean = false; 

    login(user:User): any { 
     this.jsonApiService.post('/token', user) 
      .map(
       resp => { 
        /** 
        * check if success, 
        * store token to localstorage 
        */ 
        set isLoggedIn = true 
        //return new object with data about success/error 
        return resp.json(); // return response or your new created object 

       }); 
    } 

    logout(): void { 
     this.isLoggedIn = false; 
    } 
} 

// Компонент

login(event) {  
    event.preventDefault(); 
    this.authService.login(this.user).subscribe(res => { 
    console.log(res); 
    },err => {  
    handle error 
    * return new object with data about success/error 
    });  
} 
+0

Он сказал, что не хочет и ищет другую возможность. – rinukkusu

+0

@ user348173 его до вас, если вы хотите переместить 'subscribe to component' или нет, но для некоторого API вам нужно называть тот же API в нескольких местах и ​​выполнять различные операции с результатом, в то время у вас будут проблемы, если вы использовали 'subscribe' в сервисах. – ranakrunal9

+0

Нет, вы можете передать lambdas (функции обратного вызова), чтобы содержать логику, которая затем вызывается в 'subscribe' внутри службы! :) – rinukkusu

1

Вы могли бы сделать что-то вроде этого, где вы возвращал новый наблюдаемым подключили к другому наблюдателю в области видимости функции.

Таким образом, ваш вызывающий компонент может просто подписаться на возвращаемый Observable, например. с асинхронной трубой и будет уведомляться всякий раз, когда observer.next называется

Я не проверял это, поэтому может потребоваться некоторое изменение, но я надеюсь, что это указывает на правильное направление!

login(user:User): any { 
     return new Observable((observer: any) => { 
      this.jsonApiService.post('/token', user) 
       .subscribe(
       resp => { 
        check if success, 
        store token to localstorage, 
        set isLoggedIn = true 
        obs.next(someResponse); 
        obs.complete(); 
       }, 
       err => { 
        handle error 
        obs.next(someResponse); 
        obs.complete(); 
       }); 
     } 
    } 
0

Если вы хотите, чтобы подписка на наблюдаемый должна содержаться в AuthService и хотите вернуть значение, которое является результатом асинхронной операции, это звучит как то, что вы ищете это обещание.

Для этого используется оператор RxJS toPromise. Он будет управлять subscribeunsubscribe) для Вас:

login(user: User): Promise<any> { 

    return this.jsonApiService 
     .post('/token', user) 
     .toPromise() 
     .then((result) => { 
      // check if success, 
      // store token to localstorage, 
      // set isLoggedIn = true 
      // return new object with data about success/error   
     }) 
     .catch((error) => { 
      // handle error 
      // return new object with data about success/error   
     }); 
} 
Смежные вопросы