Retrieve information from a service in Angular to populate a form

I am working on creating a form in Angular, and I need some placeholder data to fill in the form fields. This data is fetched from a service as JSON with three specific fields.

Due to my limited understanding of TypeScript, I may be making a basic mistake in my code. Here's what I have so far:

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 somewhere else
    }

    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),
    })
}   

In addition, here is the service I am using:

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}`);
    }
}

Although I know that my API returns the necessary JSON response with the three specified fields:

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

Initially, I encountered an error because my service returns an Observable. So, I modified my data variable to be:

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

However, another issue surfaced upon referencing this.data.id:

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

This confuses me since I do initialize the data in my constructor. What could I be missing here? How can I successfully retrieve the JSON data into the data property of my component?

Update:

I have made changes according to Yong Shun's suggestion:

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

Despite these updates, the same error regarding this.data.id persists:

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

Further Update:

Following Yong Shun's advice, my current implementation looks like this:

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 encounter a different error:

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

Answer №1

It's quite puzzling to encounter this error message since there seems to be no of variable present in your provided code snippet.

  1. You might want to consider adding an exclamation mark after the data variable.
public data!: {
    id: string,
    quantity: number,
    ref: string
};

This indicates that data is definitely not null.

  1. Avoid initializing data in the constructor. It's recommended to utilize Angular's lifecycle hook such as the ngOnInit method.

  2. The method this.service.getDataById(id) actually returns an Observable. Make sure to retrieve the data returned by the Observable using .subscribe() and also set the value for the form.

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),
        });
      }
    });
}

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

Display the sidenav-content over the sidenav layer

In my angular application, I am dealing with a material sidenav that shifts the sidenav content to the side when activated. The problem is that due to the structure of the sidenav being on top of the content at an HTML level from angular material, I am una ...

Angular's event listener functionality allows for seamless integration of user

I am currently working on an application and I need a method or event that is triggered every time, regardless of user interaction with the application. This would allow me to implement logic for rendering a timeout dialog. Can anyone provide insight on ho ...

What is the reason the server is not receiving the cookie?

I am currently running a nodejs express application on a server with two endpoints: POST /session - used to send back the cookie GET /resource - used to check if the cookie is sent back, returning 401 not found if it's not On the frontend, hosted on ...

Unlocking the Power of Asynchronous Data in Angular's Dynamic Form Patterns

Utilizing the dynamic form pattern in Angular has been incredibly helpful for our team. By defining our controls in ngOnInit, the form is dynamically constructed based on our needs. However, we've encountered a challenge with forms that require initia ...

Share the component with css and font via npm

I am looking to release an angular 2 component on NPM. This particular component utilizes CSS that references certain fonts. I have figured out how to publish the .ts files, but I am unsure about how to handle the CSS and font files. Here is what I curren ...

What led the Typescript Team to decide against making === the default option?

Given that Typescript is known for its type safety, it can seem odd that the == operator still exists. Is there a specific rationale behind this decision? ...

Tips for setting up terserplugin without renaming classnames

My issue involves classnames being mangled during minification, which is causing problems. I attempted to address this by setting the reserved property when mangling according to the instructions found here. However, this solution did not work for me. To ...

How can I adjust the appearance of an HTML tag within an Angular component?

I have created an Angular component with the following definition: import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'rdc-dynamic-icon-button', templateUrl: './dynamic-icon-button. ...

angular2: The element 'Validators' is not recognized

When working with Angular2, I encountered an error in Visual Studio Code that is displayed with the following message: enter image description here Here is the content of my tsconfig.json file: { "compilerOptions": { "target": "es5", "module" ...

The Jest mock is infiltrating the function logic instead of simply returning a rejected promise

The Issue at Hand I am currently working on testing the correct handling of errors when a use case function returns a rejected promise along with the appropriate status code. However, I seem to be encountering an issue where instead of getting a rejected ...

Angular EventEmitter fails to emit event

I am currently working with an Angular vertical stepper (using Angular Material) consisting of separate components for each step, with a parent component calling all these child components. My challenge is in passing data between the parent and child compo ...

Typescript error: Undefined reference to 'DhImportKeyParams'

Working on a project, I encountered an issue with a third-party library written in Typescript 3.7. The outdated library depended on the 'lib' that contained an interface called DhImportKeyParams. However, my current project uses Typescript 4.6 wh ...

Is there a way to check if a date of birth is valid using Regular Expression (RegExp) within a react form?

const dateRegex = new RegExp('/^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.] (19|20)\d\d+$/') if (!formData.dob || !dateRegex.test(formData.dob)) { formErrors.dob = "date of birth is required" ...

Issue with typescript: "Property not found in void type"

So, I've stumbled upon some code I created using Angular Bootstrap for a date picker within an event registration form (where you click new to create a new event). The objective is for the user to select a date and save it. Here's the code snippe ...

Angular 6 Error: Template Driven Form - Unable to access property 'required' in null entity

Struggling with validation issues while working on an angular 6 project with a template-driven form. Here is the HTML code snippet causing trouble: <div class="form-group"> <div class="form-group"> ...

When using ngFor, a conversion from a string literal type to a regular string occurs, resulting in an error that states: "Element implicitly has an 'any' type because an expression of type 'string' cannot be utilized..."

When utilizing the iterator *ngFor, it converts a string union literal type ("apple" | "banana") to a string type. However, when attempting to use it as an index of an array expecting the correct string union literal type, an error occu ...

Angular: Effective communication between components through routing and Observable binding ultimately results in the advancement of ngtsc(233

I designed an Angular Component named "crear-pedido" that exhibits a catalog of items (using row of products) and my aim is for the user to have the ability to click on the values in the ID column and navigate the application to a subordinate component kno ...

Error: Unable to access the 'nom_gr' property of null - encountered in Chrome

<ion-col col-9 class="sildes"> <ion-slides slidesPerView="{{nbPerPage}}" spaceBetween="5"> <ion-slide *ngFor="let slide of lesClassrooms; let i = index" (click)="saveCurrentSlide(i)"> ...

Strange behavior of Lambda function in Typescript

Within a larger class, I'm working with the following code snippet: array.map(seq => this.mFunction(seq)); After compiling using the tsc command, it becomes: array.map(function (seq) { return _this.mFunction(seq); }); Everything seems fine so f ...

Issue regarding retrieving the image using TypeScript from an external API

Hey developers! I'm facing an issue with importing images from an external API. I used the tag: <img src = {photos [0] .src} /> but it doesn't seem to recognize the .src property. Can anyone shed some light on how this is supposed to work? ...