0

In my Angular app I am making a call to the API to get some "next stage" info. Once I have that I'm parsing out the name so that I can print that to the view. I am making use of async/await within this function.

Instead of printing the string value for "stage" to the view, what I see is [Object Object].

Why is my interpolated value showing [Object Object] instead of "regular" in this case?

2
  • 4
    Try using json pipe to check what you are getting. {{ getNextStageName() || 'Not Available' | json}} Commented Nov 27, 2018 at 14:07
  • Doesn't answer your question, but I had this [Object object] issue, but I was using rxjs Subject. I had to add async pipe $mymessage | async Commented Nov 12, 2020 at 16:29

5 Answers 5

0

Try to pipe with JSON pipe to see the real value.

<span class="md-menu-text">{{ (getNextStageName() || 'Not Available') | json }}</span>

So you could see what is wrong with your value.

Sign up to request clarification or add additional context in comments.

2 Comments

This isn't an answer. Should be a comment.
| json inside {{ }} helps
0

So it looks like you are using promises for your API calls, and not Angular's HttpClientModule which uses rxjs and returns parsed JSON as the default. With that being said you probably need to parse the json in your promise...

public async getNextStage(staffId) {
    const response = await API.service.send({
        reqType: 'get',
        req: `staff/history/next`,
        reqArgs: {id: staffId}
    });
    return response.json
}

Comments

0

Instead of binding to the function, bind to a variable.

All you need to do it to declare a variable in your component like this:

nextStageName = 'Not Available';

Bind to it in the view - {{nextStageName}}

Once your service return the value, assign it to this variable.

The View will show 'Not Available' till the service get the new value. The view will be updated automatically.

Comments

0

So here's what's happening:

The property that you think is a string is actually an Object. When you're using the string interpolation syntax({{}}) on it in the template, Angular is calling the toString method on it. Calling toString on an Object results in [Object Object].

So once you get the response from the API, you'll need to make sure what exactly to print on the view. The stage name would probably be a field value on the response data that you're actually receiving from your service.

Below is an example mock(leveraging the JSONPlaceholder API) of how you'd go about doing it:

import { Component } from '@angular/core';
import { StageService } from './stage.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  stageData: any; // This would be assigned an Object that your service method results

  constructor(private stageService: StageService) {}

  async ngOnInit () {
    this.stageData = await this.stageService.getStageData();
    // Log it to the console to see it's structure and look for the property you want to use on the UI.
    // For this specific example, the response data will have a name property that I'm using on the HTML(Template)
    console.log('Got the Stage Data as: ', this.stageData);
  }
}

In the template:

<!--
  Here since the data is going to be assigned asynchronously 
  but the template would already be in the process of initialization, 
  I'm using the *ngIf directive to check. 
  If the stageData is still undefined, I'm displaying the elseBlock
-->
<div *ngIf="stageData; else elseBlock">
  <h1>Stage Name</h1>

  <p>Wrong Syntax: {{ stageData }} - Will print [Object object] as stageData is an Object and NOT A STRING</p>

  <p>Right Syntax: {{ stageData.name }}</p>
</div>

<ng-template #elseBlock>
  <h1>Loading...</h1>
</ng-template>

Here's a Sample StackBlitz for your ref.

PS: Pay close attention to the Comments.

6 Comments

Okay, if that's the case, then why when I do this: public async getNextStageName() { let stage = "Nothing yet"; console.log(typeof stage); return stage; } ... do I still get [Object Object] printed in the view? The console.log of the typeof shows this as string. So what's going on here?
You won't be able to use stage on the HTML as it is a local variable declared in your getNextStageName function. So it would be scoped only till the getNextStageName function as you've declared it with let. Another thing, it's type of is showing string inside the function as it is a string inside the funciton. But since it's an async function whatever is returned from this function is probably wrapped in as an observable. And if this is your implementation, then let me update the answer and the stackblitz for you.
But yeah, if you're returning a string from it, which is local, then why declare it as an async function. Just remove the async keyword from there and you'll be good to go. Another thing that could be an issue is that you're not calling the method in your template -You probably are doing {{ getNextStageName }} when you should have been doing {{ getNextStageName() }}
So, I was definitely doing {{ getNextStageName() || 'Not Available' }} all along. So, after all that, are you saying my original implementation minus the async and await will work? Please clarify.
If the string is local and you're declaring it with the let keyword in the getNextStageName method, then yes, you can simply remove the async keyword from the function and call the method on your template like this: {{ getNextStageName() }} and you should be good to go. I've updated my stackblitz with the same. Please feel free to check it out.
|
0

For string interpolation remember:

var x = `my name is ${name}` // CORRECT
var x = `my name is ${{name}}` // INCORRECT

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.