Join the Observable and formControl in Angular 4 by subscribing

My goal is to display the data retrieved from FireStore in the screen fields upon loading. However, the buildForm() function is being called before subscribing to the data, resulting in the failure to populate the screen fields with the FireStore data.

perfil-model.ts:

export class Perfil {
    nome: string;
}

authService.ts:

getPerfil() {
    return this.afs.doc<Perfil>(`perfil/${this.id}`)
      .snapshotChanges()
      .map(p => {
        return { ...p.payload.data() };
      });
  }

perfilUser.component.ts:

  perfil: Perfil = new Perfil();
  perfilForm: FormGroup;

  ngOnInit() {
    const subscribe = this.authService
    .getPerfil()
    .subscribe((p: any) => {
      subscribe.unsubscribe();
      this.perfil = p;
    })

    this.buildForm();
  }

  buildForm() {
    this.perfilForm = this.formBuilder.group({
      nome: this.perfil.nome,
    });
  }

perfilUser.component.html:

<form [formGroup]="perfilForm" novalidade>
        <div class="row">
          <div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
            <label for="name">Nome*</label>
            <input type="text" class="form-control" formControlName="nome" placeholder="Nome">
          </div>
</form>

Although I've confirmed that FireStore values are being returned, I'm struggling to display them on the screen.

Answer №1

Implement patchValue within the subscribe method

this.authService
    .fetchProfile()
    .subscribe((profile: any) => {
      this.profileForm.patchValue({'name' : profile.name})
    })

Answer №2

To ensure that the observable populates your form, you need to invoke the buildForm method within the subscribe function or alternatively set values within the subscribe function. Below is an illustration of this concept:

perfil.component.ts

nome:string;
constructor(){
    this.perfilForm = new FormGroup({
       "nome": new FormControl(this.nome)
    });
}    

ngOnInit() {
    const sub = this.authService
    .getPerfil()
    .subscribe((p: any) => {
         sub.unsubscribe();
         this.nome = p.nome;
    })
  }

perfil.component.html

<form [formGroup]="perfilForm" novalidade>
    <div class="row">
      <div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
        <label for="name">Nome*</label>
        <input type="text" class="form-control" formControlName="nome" placeholder="Nome" [(ngModel)]="nome">
      </div>
    </div>
</form>

Answer №3

Issue with Saving Blank Fields

Error message: When leaving a blank field, it is not saved as an empty string and results in an error.

perfilUser.component.html:

<form [formGroup]="perfilForm" novalidade>
<div class="row">
  <div class="form-group col-12 col-sm-12 col-md-7 col-lg-4 col-xl-4">
    <label for="name">Nome*</label>
    <input type="text" class="form-control" [(ngModel)]="perfil.nome" formControlName="nome" placeholder="Full Name">
  </div>

<button class="btn btn-success" type="button" (click)="saveProfile()">Save</button>

</form>

perfilUser.component.ts:

perfil: Perfil = new Perfil();

  saveProfile() {
    this.authService.createProfile(this.perfilForm.value);
  }

authService.ts:

@Injectable()
export class AuthService {

  perfil: Observable<Perfil[]>;
  userId: string;

  constructor(private afs: AngularFirestore) {
    this.afAuth.auth.onAuthStateChanged((user) => {
      if (user) {
        this.userId = user.uid;
      }
    })
}

createProfile(perfil: Perfil) {
    const userRef: AngularFirestoreDocument<Perfil> = this.afs.doc(`perfil/${perfil.userId}`);
    return userRef.set(perfil);
  }

perfilModel.ts:

export class Perfil {
    nome: string;
    ..... : string;
    ..... : string;
}

the rest of the code is at the beginning of the question

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to search through an array of object arrays in JavaScript for a specific key/value pair using lodash or any other function?

I am faced with a task involving an array of objects. Each object has a key that needs to be used to search through sets of arrays containing similar objects. The goal is to determine if all the arrays contain the same value for a specific key in my object ...

Using Regular Expressions as an Alternative to Conditionals

My knowledge of RegEx is limited, but I'm trying to make the following expression work with Javascript/Typescript: /^({)?(?(1)|(\()?)[0-9A-F]{8}(-)?([0-9A-F]{4}(?(3)-)){3}[0-9A-F]{12}(?(1)}|(?(2)\)))$/i This RegEx is used to check if a str ...

Updated the application to Angular 6 but encountered errors when attempting to run npm run build --prod. However, running the command npm run build --env=prod was executed without any issues

Running the command npm run build -- --prod results in the following error messages: 'PropertyName1' is private and can only be accessed within the 'AppComponent' class 'PropertyName2' does not exist in type 'AppCompo ...

Exploring the Incorporation of String as a Component Identifier in React and TypeScript

My input component can render either a textarea component (from a library) or a regular input. Check out the code below: import React, { useEffect, useRef, useState } from 'react' import './AppInput.css' interface Props { placehold ...

What is the method for passing an element in Angular2 Typescript binding?

Is there a way to retrieve the specific HTML dom element passed through a binding in Angular? I'm having trouble figuring it out, so here is the relevant code snippet: donut-chart.html <div class="donut-chart" (donut)="$element"> ...

Leveraging Angular for Parsing JSON Data

I have a JSON object that I want to use in my code. The goal is to assign the values of certain properties from the JSON object to four variables in my Angular project. These variables are named as follows: authorText : string; titleText : string; duratio ...

Quirky happenings in Typescript

TS Playground function foo(a: number, b: number) { return a + b; } type Foo1 = typeof foo extends (...args: unknown[]) => unknown ? true : false; // false type Foo2 = typeof foo extends (...args: any[]) => unknown ? true : false; // true What is ...

Testing HTTP Requests in Angular applications

I am currently utilizing Angular 9+. When it comes to unit testing services that utilize httpClient for making http requests, I found the official documentation from the Angular Team to be very helpful. By following their guidelines, I was able to success ...

Managing dynamic text within a label using Playwright

In my Playwright Typescript test, I have the following code snippet: await page.goto('https://demoqa.com/'); await page.getByLabel('Optionen verwalten', { exact: true }).click(); await page.locator('label').filter({ hasText: & ...

Error with Array type encountered in Typescript's find method

I am encountering an issue with code that looks like this: type X = { test: number; x: number; }[]; type Y = { test: number; y: number; }[]; type Z = { test: number; z: number; }[]; export const testFunc = (arg: X | Y | Z) => { return a ...

Loading the Angular 2 library with the help of SystemJS

I recently went through the Angular2 quickstart guide on angular.io and came across their use of systemJs for app loading. Instead of importing, they load angular2, rx.js, and angular2.dev.js via script references. Is there a way to import these scripts? ...

A guide to implementing angularjs app.service and $q in typescript

I am fairly new to TypeScript and AngularJS and I am struggling to find the correct answer for my issue. Below is the relevant code snippet: export class SidenavController { static $inject = ['$scope', '$mdSidenav']; constructor(p ...

Ensuring the completion of all validations in Angular 4

Currently, I'm working on a project that involves 3 FormControls. I am in need of a validation process that ensures either all three have values selected or none at all. Is there a method to achieve this type of validation? ...

Unable to iterate over a JSON response from a POST request in Angular 8

I am attempting to iterate through a JSON object that is returned after making a POST request to my REST API. However, I'm encountering the following error: DatetodateComponent.html:33 ERROR Error: Cannot find a differ supporting object '[objec ...

To successfully transfer a file (whether it be an excel or csv file) into a nodejs environment and then have it update in a mongodb database, follow

Can anyone guide me on how to upload a file, ensuring only Excel or CSV formats are accepted? I then need to read the file using Node.js and update it in a MongoDB database table. Technologies used: Angular 5 for front end, Node.js and MongoDB for backend ...

Tips for obtaining a redirect URL using Angular5

After receiving a temporary URL from a JSON server, I found out that it redirects to a permanent URL. My goal is to capture and store this redirect (permanent) URL in my database. Do you think this can be achieved with Angular 5? ...

Using HttpClient to post data to Django backend for seamless information transfer

Having trouble sending data from my Angular front end to my Django backend. I've triple-checked the code on the frontend... const post_data = { email: form.value.email, password: form.value.password } const headers = new HttpHeaders({ 'Con ...

A guide on passing an ngFor object variable to a function

I am trying to display subcategories for each category in my *ngFor list. The subcategory data is retrieved from Firebase using the category_id, but I am struggling to pass the category_id from the HTML to the function for every member of the category. ho ...

Create a variable and save data into it

I successfully fetched data from Firebase but I am having trouble storing it in a declared variable. I need to store the data in a variable so that I can use it in another method. Any assistance would be greatly appreciated. Below are the code snippets I ...

Angular 2.0's development of modules and implementation of shadow DOM focuses on supporting a left

My website supports "right to left" languages like Arabic. When the language is Arabic, I add the dir="rtl" attribute to the body tag. This aligns all inline positioned children from the right side, even within custom components. Now, I want a custom styl ...