Как я могу заставить угловую защиту маршрута или службу, которую она вызывает, ждать ответа перед оценкой логического значения?

Я пытаюсь реализовать некоторую базовую логику в защите маршрута, чтобы убедиться, что пользователь имеет право доступа к URL-адресу.

Когда пользователь щелкает ссылку из списка, я беру идентификатор документа firestore и передаю этот идентификатор в качестве параметра URL на следующую страницу. С помощью этого метода URL-адрес показывает идентификатор документа, чтобы пользователи могли изменить идентификаторы на то, к чему у них нет доступа.

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

Я предполагаю, что мне нужно реализовать какое-то наблюдаемое, но я не уверен, в какой момент процесса я должен испускать наблюдаемое и где я должен подписаться (сервис или охрана?). Я начал с предположения, что некоторые вызовы должны быть в сервисе, но, может быть, было бы лучше, чтобы они были в самой защите? Я ценю любую помощь.

Охранник маршрута

canActivate(route: ActivatedRouteSnapshot): boolean {
    this.pid = route.paramMap.get('pid')
    if (this.authService.isPartyAuth(this.pid) !== true) {
      this.router.navigate(['home'])
    }
    return true;
  }

служба аутентификации

liveUid устанавливается в конструкторе, а также partyCollectionRef

isPartyAuth(pid: string) {

    this.partyCollectionRef.doc(pid).ref.get().then((doc) => {
      if (doc.exists) {
        this.partyUserId = doc.data().uid
      } else {
        console.log("No such document!");
      }
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });
    
    return this.partyUserId == this.liveUid && this.partyUserId !== undefined && this.liveUid !== undefined ? true : false;
  }
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
0
41
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

canActivate() {
  // add 'return'
  return this.authService.isPartyAuth(this.pid)
   // change this!
   // .subscribe(resp=> {
   .map(resp=> {
     if(!resp) {
        this.router.navigate(['home'])
        return false;
     }
     return true;
   }); 
 }
Ответ принят как подходящий

Я сделал пару небольших изменений и получил это работает:

Охранник маршрута

Я сделал всю функцию асинхронной и добавил ожидание к вызову службы.

  async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {

    this.pid = route.paramMap.get('pid')

    if (await this.authService.isPartyAuth(this.pid) !== true) {

      this.router.navigate(['home'])

    }
    
    return true;
  }

}

Служба аутентификации

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

isPartyAuth(pid: string) {

   return this.partyCollectionRef.doc(pid).ref.get().then((doc) => {
      if (doc.exists) {
        this.partyUserId = doc.data().uid
        return this.partyUserId == this.liveUid && this.partyUserId !== undefined && this.liveUid !== undefined ? true : false;
      } else {
        console.log("No such document!");
        return false
      }
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });


  }

Другие вопросы по теме