Repository: oppia/oppia
File: core/templates/pages/topic-viewer-page/practice-tab/practice-tab.component.ts (TypeScript)

Code before:
      } else {
        this.subtopicMasteryArray.push(0);
      }
    }
    this.selectedSubtopicIndices = Array(this.availableSubtopics.length).fill(
      false
    );
    this.clientWidth = window.innerWidth;
    if (
      this.displayArea === 'topicViewer' &&
      this.urlService.getPathname().startsWith('/learn')
    ) {
      this.topicUrlFragment =
        this.urlService.getTopicUrlFragmentFromLearnerUrl();
      this.classroomUrlFragment =
        this.urlService.getClassroomUrlFragmentFromLearnerUrl();
    } else if (
      this.displayArea === 'topicViewer' &&
      this.urlService.getPathname().startsWith('/topic_editor')
    ) {
      this.topicId = this.urlService.getTopicIdFromUrl();
      let topicDataPromise =
        this.editableTopicBackendApiService.fetchTopicAsync(this.topicId);
      topicDataPromise
        .then(topicData => {
          this.topicUrlFragment = topicData.topicDict.url_fragment;
          this.classroomUrlFragment = topicData.classroomUrlFragment ?? '';
        })
        .catch(error => {
          console.error(error);
        });
    }
    this.topicNameTranslationKey =
      this.i18nLanguageCodeService.getTopicTranslationKey(
        this.topicId,
        TranslationKeyType.TITLE
      );
    this.getTranslatedTopicName();
    this.subscribeToOnLangChange();
  }

  ngOnDestroy(): void {
    this.directiveSubscriptions.unsubscribe();
  }

  subscribeToOnLangChange(): void {
    this.directiveSubscriptions.add(
      this.translateService.onLangChange.subscribe(() => {
        this.getTranslatedTopicName();
      })
    );

Review comment (suggestion):
topicUrlFragment is a input. Best to avoid directly modifying input variables, which can cause side effects. If topicUrlFragment isn't being passed, we can convert this to a local variable. This applies to other input variables like classroomUrlFragment as well.

Code after:
    this.selectedSubtopicIndices = Array(this.availableSubtopics.length).fill(
      false
    );
    this.clientWidth = window.innerWidth;
    this.topicNameTranslationKey =
      this.i18nLanguageCodeService.getTopicTranslationKey(
        this.topicId,
        TranslationKeyType.TITLE
      );
    this.getTranslatedTopicName();
    this.subscribeToOnLangChange();
  }

  ngOnDestroy(): void {
    this.directiveSubscriptions.unsubscribe();
  }

  subscribeToOnLangChange(): void {
    this.directiveSubscriptions.add(
      this.translateService.onLangChange.subscribe(() => {
        this.getTranslatedTopicName();
      })
    );
  }

  getTranslatedTopicName(): void {
    if (this.isTopicNameTranslationAvailable()) {
      this.translatedTopicName = this.translateService.instant(
        this.topicNameTranslationKey
      );
    } else {
      this.translatedTopicName = this.topicName;
    }
  }

  isTopicNameTranslationAvailable(): boolean {
    return (
      this.i18nLanguageCodeService.isHackyTranslationAvailable(
        this.topicNameTranslationKey
      ) && !this.i18nLanguageCodeService.isCurrentLanguageEnglish()
    );
  }

  checkIfQuestionsExist(subtopicIndices: boolean[]): void {
    const skillIds: string[] = [];
    this.questionsStatusCallIsComplete = false;
    for (let idx in subtopicIndices) {
      if (subtopicIndices[idx]) {
        skillIds.push(...this.availableSubtopics[idx].getSkillIds());
      }
    }