Angular is not able to access the value of a promise in a different function after it has been retrieved

I have a form with default values that should be added to the form fields when it appears. There are two functions: #1 for fetching data from the backend and #2 for displaying the form:

person$: any;

ngOnInit() {
  this.getPersonData(123)
  this.buildPersonForm()
}

getPersonData(id: number) {
   this.personService.getDetails(id)
     .subscribe((data) => {
       this.person$ = data
     }
}

buildPersonForm() {

  // I need to access this.person$.firstname here

  console.log(this.person$.firstname) // returns undefined
  this.PersonForm = this.fb.group({
     firstname: [null, Validators.required],
  })
}

If I use the following code in the HTML template, it works:

<input matInput placeholder="Firstname" formControlName="firstname" value="{{person$?.firstname}}">

However, I want to know how to access it inside the component itself, not just in the HTML template.

Angular CLI: 7.0.2
Node: 10.12.0
OS: darwin x64
Angular:
...

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.10.2
@angular-devkit/core         7.0.2
@angular-devkit/schematics   7.0.2
@schematics/angular          7.0.2
@schematics/update           0.10.2
rxjs                         6.3.3
typescript                   3.1.3

Answer №1

To trigger the execution of buildPersonForm, simply call it once the getPersonData observable has completed.

ngOnInit() {
  this.getPersonData(123);
}

getPersonData(id: number) {
   this.personService.getDetails(id)
     .subscribe((data) => {
        this.person$ = data
      },
     null,
      () => this.buildPersonForm()
    }

Alternatively, you can place buildPersonForm directly within the subscribe method to achieve the same result.

ngOnInit() {
  this.getPersonData(123);
}

getPersonData(id: number) {
   this.personService.getDetails(id)
     .subscribe((data) => {
       this.person$ = data;
       this.buildPersonForm();
     }
}

Lastly, another approach is to utilize async/await.

async ngOnInit() {
  this.person$ = await this.getPersonData(123).toPromise();
  this.buildPersonForm();
}

Answer №2

When using FormControl, the default value will be taken from the first item in the array below.

To achieve this, we can utilize async/await.

async ngOnInit() {
    this.person$ = await this.personService.getDetails(id).toPromise();
    this.buildPersonForm();
}

Subsequently, we set the value to the FormControl in the "buildPersonForm()" method.

this.PersonForm = this.fb.group({
    firstname: [this.person$.firstname, Validators.required],
})

Additionally, in the HTML, the value binding is not necessary if you have included "formControlName" as specified.

<input matInput placeholder="Firstname" formControlName="firstname">

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

I have to make sure not to input any letters on my digipas device

There is a slight issue I am facing. Whenever I input a new transfer of 269 euros with the bank account number BE072750044-35066, a confirmation code is required. The code to be entered is 350269. https://i.stack.imgur.com/YVkPc.png The digits 350 corres ...

Enumerate the names of the private properties within the class

I am working on a problem where I need to use some of the class properties as values in a map within the class. In the example below, I have used an array instead of a map because when a property is marked private, it is not included in the keyof list. How ...

Develop a TypeScript class by incorporating a static function from an external library, while ensuring type safety

I am looking to enhance the capabilities of the rxjs5 Observable class by adding a static function. While this can be easily accomplished in plain JavaScript: var myStaticFn = function() { /* ... */ }; Observable.myStaticFn = myStaticFn; this approach w ...

Angular issue: Unable to scroll to top after route change and loading a new component

In the process of developing a simple Angular application, I encountered an issue. When navigating from my home page to the services page, scrolling down, and then returning to the home page, the scroll position is always set to the bottom of the page. My ...

What is the best method to retrieve the data received from a back-end system once an Upload request with form-data has been completed?

I've created an upload method to monitor the progress of file uploads. The upload process is successful, however, at the end, my backend server sends back an object (register) containing information about the uploaded file (such as ID). I'm unsu ...

React application experiencing freezing when setInterval function is utilized

I've been working on incorporating Conway's Game of Life into a React project, but I'm encountering freezing issues whenever a new generation is triggered. My assumption is that the problem lies in the excessive overhead from constant DOM re ...

When converting to TypeScript, the error 'express.Router() is not defined' may

Currently, I am in the process of converting my express nodejs project from JavaScript to TypeScript. One of the changes I've made is renaming the file extension and updating 'var' to 'import' for "require()". However, there seems ...

Organize the attributes of components on the following line in Visual Studio Code

Is there a method to configure the VS code formatter for Angular 2+ templates to ensure that attributes are wrapped in a new line? I prefer this formatting: <app [input1]="input1$ | async" [input2]="input2$ | async" (inputChanged)="set ...

Set up Nginx to host Angular static files and act as a reverse proxy for express

Recently, I've started using Nginx for serving static Angular files and proxying to a backend Express server. Both the frontend (with Nginx) and backend are dockerized. My frontend consists of a button that makes a request to fetch data from Express. ...

Utilizing getters and setters with v-model in a class-based component: A step-by-step guide

Transitioning from an angular background to vuejs has been challenging for me as a newbie. I've encountered issues while trying to bind setter/getter in v-model for an input field. Interestingly, when I directly bind it to a variable, everything works ...

Validating a field conditionally upon submission

Adding a required validation conditionally to the "imageString" field upon submission, but the expected required validation is not being set. Initializing the form. constructor(){ this.poeForm = this.fb.group({ imageString: [""], imageFileNam ...

Challenges with implementing Typescript in Next.js and the getStaticProps function

Having trouble with the implementation of getStaticProps where the result can be null or some data. The typings in getStaticProps are causing issues, even after trying conditional props. Any suggestions? type ProductType = { props: | { ...

Is there a way to implement personalized error management in TypeScript with Express?

For a while now, I have been using JavaScript to create my APIs but recently made the switch to TypeScript. However, I keep encountering errors along the way. One particular error handler I have set up is for when a route cannot be found, as shown below: i ...

How to properly pass a parameter value to an Angular service when using inject.get in the constructor

After experimenting with injecting services in Angular, I encountered an issue when trying to call LogService within GlobalErrorHandler. Despite my best efforts, the code below just wouldn't work. I discovered that the problem stemmed from not passin ...

Explaining the functionality of reserved words like 'delete' within a d.ts file is essential for understanding their

I am currently in the process of generating a d.ts file for codebooks.io, where I need to define the function delete as an exported top-level function. This is what my codebooks-js.d.ts file looks like at the moment: declare module "codehooks-js" ...

Setting a value in the selectpicker of rsuitejs involves assigning a specific value to the

const _DATA = [{ code: 'code1', name: 'Jagger' },{ code: 'code2', name: 'Tigger' },{ code: 'code3', name: 'Lion' }] <SelectPicker data={_DATA.map(x => {return {label: x.n ...

"Is it possible in Typescript to set the parameters of a returning function as required or optional depending on the parameters of the current

I am currently exploring Typescript and attempting to replicate the functionality of styled-components on a smaller scale. Specifically, I want to make children required if the user passes in 'true' for the children parameter in createStyledCompo ...

When running jest unit tests, an error is thrown stating that includes() and toLowerCase are not functions

MyComponent.js contains both toLowerCase and includes methods on the props. However, when attempting to perform unit testing on MyComponent, I encounter an issue where the functions toLowerCase() and includes() are not recognized as valid. Within MyCompon ...

How to efficiently import an external ES module from a URL using TypeScript

I've recently started experimenting with Observable notebooks and I must say, it's been a great experience so far. Now, my next goal is to integrate a notebook into my web app. The following vanilla JavaScript code using JavaScript modules accomp ...

Implementing a Loading Spinner with Angular4's HttpClient Interceptor

Within this code snippet, you will find the interceptor I created to manage the spinner directly through the interceptor itself. @Injectable() export class ApiInterceptor implements HttpInterceptor { constructor(private _globalSpinnerService: GlobalSp ...