Home > Back-end >  Angular - Get data from a service for a form
Angular - Get data from a service for a form

Time:01-11

I want to create a form in Angular, but I need some data for placeholders. This data is retrieved from a service as JSON with three fields.

I don't really understand how TypeScript works so I might be doing a very basic mistake, but here's the code :

export class Component{
    public data:{
        id: string,
        quantity: number,
        ref: string
    };

    constructor(private service: Service){
        this.data = this.service.getDataById(id) // I get the id from elsewhere
    }

    ngOnInit(): void {}

    form = new FormGroup({
        id: new FormControl(this.data.id, Validators.required),
        ref: new FormControl(this.data.ref, Validators.required),
        quantity: new FormControl(this.data.quantity, Validators.required),
    })
}   

Also here is my service:

export class service{
    /* @ngInject */
    constructor(private http: HttpClient) {}

    getDataById(id: number): Observable<{
        id: string;
        quantity: number;
        ref: string;
    }> {
        return this.http.get<{
            id: string;
            quantity: number;
            ref: string;
        }>(`api/getOfById/${id}`);
    }
}

I know I get the values because my API returns the JSON response with the three fields:

{
  creationTimestamp: /*the time*/, 
  data:{
    id: /*value*/,
    quantity: /*value*/,
    ref: /*value*/
  }
}

First I got an error as my service returns an Observable, so I modified my data to be:

public data: Observable<{
    id: string;
    quantity: number;
    ref: string;
  }>;

But then I get an error on my this.data.id:

TS2729: Property 'data' is used before its initialization.

I don't understand this error as the data is initialized in my constructor.

What am I missing here? How do I get the data from my JSON to the data in my component?

Update:

Now I have this:

export class Component{
  data: { id: string; quantity: number; ref: string };
  constructor(
    private service: Service
  ) {
    this.service
      .getDataById(id)
      .subscribe((value) => {
        this.data = value;
      });
  }
  //...
}

but I still have the same error : this.data.id:

TS2729: Property 'data' is used before its initialization.

Update 2:

After Yong Shun's answer, now I have:

export class Component {
  data!: { id: string; quantity: number; ref: string };
  constructor(
    private service: Service
  ) {}

  ngOnInit(): void {
    this.service
      .getDataById(id)
      .subscribe((value) => {
        this.data = value;
      });
  }

  form = new FormGroup({
    id: new FormControl(this.data.id, Validators.required),
    ref: new FormControl(this.data.ref, Validators.required),
    quantity: new FormControl(this.data.quantity,Validators.required),
  })
}

Now I get the error:

TypeError: Cannot read properties of undefined (reading 'id')

CodePudding user response:

This is a weird error message as I don't see any of variable from your attached code.

  1. Possibly try to add an exclamation mark after the data variable.
public data!: {
    id: string,
    quantity: number,
    ref: string
};

This represents data is not null.

  1. Don't perform data initialization in constructor. Use the Angular lifecycle hook such as ngOnInit method.

  2. this.service.getDataById(id) returns an Observable. You should grab the data returned from the Observable with .subscribe(). Also, assign the value for the form as well.

form!: FormGroup;

constructor(private service: Service) {}

ngOnInit(): void {
  this.service.getDataById(id)
    .subscribe({
      next(data) => {
        this.data = data;

        this.form = new FormGroup({
          id: new FormControl(this.data.id, Validators.required),
          ref: new FormControl(this.data.ref, Validators.required),
          quantity: new FormControl(this.data.quantity, Validators.required),
        });
      }
    });
}
  • Related