Home > Software design >  Angular wait for http get
Angular wait for http get

Time:02-16

I am currently working on the frontend of an api in which I have an Input field which I want to validate to disable the submit button as long as the input is not unique.

My Component looks somewhat like this:

export class CategoryCreateComponent implements OnInit {
  categoryNamesInUse: Category[];

  categoryCreateForm: FormGroup;

  constructor(private categoryService: CategoryService) {}

  ngOnInit(): void {
    this.getAllUsedNames();

    this.categoryCreateForm = new FormGroup({
      categoryName: new FormControl('', [
        Validators.required,
        Validators.minLength(1),
        this.invalidCategoryNames.bind(this),
      ]),
    });
  }    
  
  getAllUsedNames() {
    this.categoryService
      .findAllByUser()
      .pipe(
        map((categories) => {
          const usedNames = [];
          for (const key in categories) {
            usedNames.push(categories[key].name);
          }
          return usedNames;
        })
      )
      .subscribe((categoryNames) => (this.categoryNamesInUse = categoryNames));
  }
    
  invalidCategoryNames(control: FormControl): { [message: string]: boolean } {
    if (this.categoryNamesInUse.indexOf(control.value) !== -1) {
      return { categoryNameAlreadyInUse: true };
    }
    return null;
  }
}

The problem is, that the categoryNamesInUse[] is undefined and I don't know how to wait for my getAllUsedNames() method.

CodePudding user response:

I guess you don't share your code literally so I am not sure but you might define a boolean variable (isSubmitButtonDisabled = true) and move this part:

this.categoryCreateForm = new FormGroup({
      categoryName: new FormControl('', [
        Validators.required,
        Validators.minLength(1),
        this.invalidCategoryNames.bind(this),
      ]),
    });

into here:

.subscribe((categoryNames) => {
    this.categoryNamesInUse = categoryNames;
    --moved block--
    isSubmitButtonDisabled = false;
});

CodePudding user response:

Ozan's answer is correct, but I'll provide an async / await solution that you might prefer.

async ngOnInit(): Promise<void> {
    await this.getAllUsedNames();

    this.categoryCreateForm = new FormGroup({
      categoryName: new FormControl('', [
        Validators.required,
        Validators.minLength(1),
        this.invalidCategoryNames.bind(this),
      ]),
    });
  }

getAllUsedNames(): Promise<void> {
    return new Promise<void>((resolve) => {
      this.categoryService
        .findAllByUser()
        .pipe(
          map((categories: any[]) => {
            const usedNames = [];
            for (const key in categories) {
              usedNames.push(categories[key].name);
            }
            return usedNames;
          })
        )
        .subscribe((categoryNames: any) => {
          this.categoryNamesInUse = categoryNames;
          resolve();
        });
    });
  }
  • Related