0

I have an array of objects like this:

[{
  position: "Software Developer",
  company: "Big company",
  details: [
    "task1","task2,"task3"
  ]
},
{
  position: "Software Developer",
  company: "Another Big company",
  details: [
    "task1a","task2a,"task3a"
  ]
}]

I read that from the service in my component:

ngOnInit() {
    this.data.getExperience().subscribe(
      data => this.experience$ = data
    )
  }

In my html I iterate over this array but inside the loop I would like to iterate over details as well. I've tried a few approaches including the below one but I don't really understand how that works here. How to approach it correctly?

<li *ngFor='let experience of experience$'>
    <!--<a routerLink='/details/{{ user.id }}'>{{ user.name }}</a>-->
    <ul>
      <li class="position">{{ experience.position }}</li>
      <!--<li><a href='http://{{ user.website }}'>{{ user.website }}</a></li>-->
      <li class="company">{{ experience.company}}<span class="dates">  {{ experience.dates}}</span></li>
      <ul class="details" *ngFor='let d of experience.details$'></ul>
        <li>{{ d }}</li>
    </ul>
  </li>

2 Answers 2

2

$ is generally suffixed after a property name if that property contains an Observable value. This is done as a naming convention as stated in the Angular Guide here:

Because Angular applications are mostly written in TypeScript, you will typically know when a variable is an observable. Although the Angular framework does not enforce a naming convention for observables, you will often see observables named with a trailing “$” sign.

This can be useful when scanning through code and looking for observable values. Also, if you want a property to store the most recent value from an observable, it can be convenient to simply use the same name with or without the “$”.

Since you're already subscribing to the Observable and the experience$ won't be an Observable and instead it would be an array, you should consider naming the property differently.

Try this without the $.

The li for details is also not in the ul. So fix it by doing the following:

<li *ngFor='let experience of experiences'>
  <!--<a routerLink='/details/{{ user.id }}'>{{ user.name }}</a>-->
  <ul>
    <li class="position">{{ experience.position }}</li>
    <!--<li><a href='http://{{ user.website }}'>{{ user.website }}</a></li>-->
    <li class="company">{{ experience.company}}<span class="dates">  {{ experience.dates}}</span></li>
    <ul class="details" *ngFor='let d of experience.details'>
      <li>{{ d }}</li>
    </ul>

  </ul>
</li>

Also make this change in your Component Class:

import { Component } from '@angular/core';
import { DataService } from './data.service';

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

  experiences: any[];

  constructor(private data: DataService) {}

  ngOnInit() {
    this.data.getExperience().subscribe(
      data => this.experiences = data
    )
  }
}

Here's a Working Sample StackBlitz for your ref.

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

1 Comment

I tried this and get "ERROR TypeError: Cannot read property 'value' of undefined" on the elements that has details (for object with no details code works fine)
0

You have a typo just remove the $ after details. Also, do not use $ for non-observable variable, as this naming convention is usually used to identify observables.

<li *ngFor='let experience of experience$'>
    <!--<a routerLink='/details/{{ user.id }}'>{{ user.name }}</a>-->
    <ul>
      <li class="position">{{ experience.position }}</li>
      <!--<li><a href='http://{{ user.website }}'>{{ user.website }}</a></li>-->
      <li class="company">{{ experience.company}}<span class="dates">  {{ experience.dates}}</span></li>
      <ul class="details" *ngFor='let d of experience.details'></ul>
        <li>{{ d }}</li>
    </ul>
  </li>

1 Comment

Thanks for the comment about the convention, it's changed :) About the solution: please check my comments for the answer above yours.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.