Angular get - карта внутри карты - PullRequest
1 голос
/ 29 июня 2019

Я пытаюсь вызвать метод API внутри карты, но второй вызов API никогда не выполняется.Нет ошибок консоли.

//This method is not being called - Not hitting the API method
this.getUserPermissions(localStorage.getItem('user_ref'));

Просто интересно, не могу ли я вызвать карту внутри карты?

Ниже мой код.

  public isAuthenticated() {

    if (!this.loggedIn)
      this.redirectToLogin();

    return this.httpClient.get<boolean>(`${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`, {
      params: { token: this.getToken }
    }).map( /// <<<=== use `map` here
      (response) => {

        if (response !== null) {

          var receivedToken = response["securityStamp"];
          var availableToken = localStorage.getItem('access_token');

           //Check if received a refreshed token. (tokens are refreshed every 15 minutes)
          if (receivedToken && receivedToken !== availableToken) {

            localStorage.removeItem('access_token');
            localStorage.setItem('access_token', response["securityStamp"]);

          }

           this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));


        }

        let data = response;
        if (data == null)
          return false;
        else
          return true;

      }
    );

  }

  getUserPermissions(user_ref) {

    if (!this.loggedIn)
      this.redirectToLogin();

    const httpParams: HttpParamsOptions = { userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A" } as HttpParamsOptions;

    const httpOptions = {
      params: new HttpParams(httpParams),
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.getToken
      })
    };

    return this.httpClient.get<Array<any>>(`${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`, httpOptions).map( /// <<<=== use `map` here
      (response) => {

        if (response["status"] == 401) {
          this.redirectToLogin();
        }
        else if (response["status"] < 200 || response["status"] >= 300) {
          throw new Error('This request has failed ' + response["status"]);
        }

        this.user_permissions = response;
        return response;
      }
    );

  }

Ответы [ 3 ]

2 голосов
/ 29 июня 2019

Какую версию Angular (более важно, rxjs) вы используете?

Помните, что HttpClient возвращает и Observable (ленивая наблюдаемая, которая ничего не будет делать, пока вы не подпишетесь на нее).

https://angular.io/guide/http

Поскольку ваш метод isAuthenticated возвращает метод Get HttpClient, ваш isAuthenticated возвращает наблюдаемое ожидание для подписки.

Подписка на наблюдаемую HttpClient сделает httpcall, вызовите следующий обработчик наблюдателей при получении ответа, а также вызовите обработчик on complete, если таковой имеется.Я бы порекомендовал почитать об Observables здесь.https://www.learnrxjs.io/

// Doing this will not do anything as the observable has not been subscribed to.
this.httpClient.get<boolean>(`...`);

// Subscribing to the HttpClient will make the request
this.httpClient.get<boolean>(`...`)
    .subscribe((response) => {

      // do something with the response

});

Как вы сказали, первый HttpCall сделан, я предполагаю, что вы подписываетесь на метод isAuthenticated, когда вызываете его?то есть

isAuthenticated().subscribe( (response) => {
 //
})

Обратите внимание, что ваш getUserPermissions также возвращает метод HttpClient (наблюдаемый), но когда вы вызываете его this.getUserPermissions(localStorage.getItem('user_ref'));, он никогда не подписывается и, следовательно, никогда не вызывается.

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

public isAuthenticated() {

    // ...

    return this.httpClient.get<boolean>('...').map(
      (response) => {

           // Subscribe to the second Http call

           this.getUserPermissions(localStorage.getItem('user_ref'))
             .subscribe( (response) => {
               // do something with the second
           })
       })
}

Пара дополнительных замечаний;Оператор map, к которому вы присоединяетесь к методу httpClient.get, с rxjs v6 устарел в пользу оператора канала.

см .: https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md

Итак, это

this.httpClient.get<boolean>('...')
    .map( ... )
    .subscribe(...)

Теперь должно быть написано так:

this.httpClient.get<boolean>('...')
  .pipe(        // <- Pipe the operators
    map( ... ),
    map( ... )
  )
  .subscribe( ...)

Хотя за пределами первоначального вопроса, я бы посмотрел на рефакторинг вашего кода и использовал бы доступные операторы rxjs / для лучшего управления потоком.

this.httpClient.get<boolean>('...')
    .pipe(       
      map(( response ) => {
        // some logic
        return something;
      }),
      map( (something) => localStorage.getItem('user_ref')),
      switchMap( (userRef) => this.getUserPermissions(userRef)), // <- switchMap to a new observable
    )
    .subscribe( (responseFromGetUserPermissions) => {
       // This value is now the return of getUserPermissions because of switchMap

    })

rxjs / observable - действительно мощный паттерн, я настоятельно рекомендую потратить много времени на изучение того, как извлечь из них максимальную пользу.

С уважением, Jono

2 голосов
/ 29 июня 2019

Это потому, что функция .map() возвращает не подписку, а наблюдаемую.Если вам нужно взаимодействовать с ответом от вызова API HttpClient, вам нужно подписаться на метод .get() или .post(), который вы вызываете.

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

firstUrl = `${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`;
secondUrl = `${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`;

public isAuthenticated() {

    if (!this.loggedIn) this.redirectToLogin();
    return this.httpClient.get<boolean>(this.firstUrl, {params: {token: this.getToken}}).subscribe(
        (response) => {
            if (response !== null) {
                let receivedToken = response["securityStamp"];
                let availableToken = localStorage.getItem('access_token');
                if (receivedToken && receivedToken !== availableToken) {
                    localStorage.removeItem('access_token');
                    localStorage.setItem('access_token', response["securityStamp"]);
                }
                this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));
            }
            return response != null;
        },
        (error) => console.log(error)
    );
}

getUserPermissions(user_ref) {
    if (!this.loggedIn) this.redirectToLogin();
    const httpParams: HttpParamsOptions = {userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A"} as HttpParamsOptions;
    const httpOptions = {
        params: new HttpParams(httpParams),
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + this.getToken
        })
    };
    return this.httpClient.get<Array<any>>(this.secondUrl, httpOptions).subscribe(
        (response) => {
            if (response["status"] == 401) {
                this.redirectToLogin();
            } else if (response["status"] < 200 || response["status"] >= 300) {
                throw new Error('This request has failed ' + response["status"]);
            }
            this.user_permissions = response;
            return response;
        },
        (error) => console.log(error)
    );
}
0 голосов
/ 30 июня 2019

Конечно, вы можете вызывать map внутри карты, но проблема, для которой вы не вызываете API, заключается в том, что ваш метод getUserPermissions возвращает Observable, а не данные пользователя.

Я рекомендуючто вы измените дизайн этой части, следуя реактивному подходу.

Вы можете прочитать эту ссылку .

Надеюсь, это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...