Home > Enterprise >  Why am I getting a NG0901 error when I am not performing any data change?
Why am I getting a NG0901 error when I am not performing any data change?

Time:02-08

In the following code segment, I am iterating over ardene.section1.items. I have logged this array to the console to verify that it does exist. The "BEFORE FOR LOOP" test is printed to the screen but the "INSIDE FOR LOOP" test is never printed. And I get and NG0901 error which Angular tells me is a ngDoCheck error.

<div >
BEFORE FOR LOOP
<div 
    *ngFor="let item of ardene.section1.items">
    INSIDE FOR LOOP
    <img  
        src=`{{ardene.assetPath}}{{item.img}}`>
    <div>
        <h5 >{{item.name}}</h5>
        <h6 >{{item.description}}<br></h6>
        <a>
            <h6 >Shop Now</h6>
        </a>
    </div>
</div>    

The component code that produces ardene.section1.items is shown below.

  constructor(
    private store:Store<{ardeneState}>
  ) { }

  ngOnInit(): void {
    this.subscribeToReduxStores();
  }

private subscribeToReduxStores = () => {
const ardene$ = this.store.select(state => {
  return state.ardeneState
})

ardene$.subscribe(ardene => {
  this.ardene = ardene;

  console.log('ardene.section1.heading', this.ardene.section1.heading)
  console.log('ardene.section1.items', this.ardene.section1.items)
  console.log('ardene', this.ardene)
})
  }

The data originates from the redux store:

const initialState = {
  assetPath: 'app/category/ladies-apparel/ardene/assets/img/',

  section1: {
    heading: 'New Denim Guide',
    subheading: "EVERYBODY'S OBSESSING OVER THESE STYLES",
    items: {
      img: 'ardene-6.jpg',
      name: 'Mom Jeans',
      description: 'The vintage silhouette',
      link: '',
    },
  },
};

Error:

ERROR Error: NG0901
at e.find (main.10edf50a2ef1763e.js:1:146206)
at h.ngDoCheck (main.10edf50a2ef1763e.js:1:43158)
at Vs (main.10edf50a2ef1763e.js:1:56860)
at Bs (main.10edf50a2ef1763e.js:1:56661)
at yr (main.10edf50a2ef1763e.js:1:56381)
at ro (main.10edf50a2ef1763e.js:1:76106)
at Gy (main.10edf50a2ef1763e.js:1:82951)
at _y (main.10edf50a2ef1763e.js:1:76845)
at ro (main.10edf50a2ef1763e.js:1:76856)
at Hy (main.10edf50a2ef1763e.js:1:76404)

CodePudding user response:

You are getting error because you are trying to iterate over an object instead of an array when using *ngFor.

// ardene.section1.items is an object and not an array
*ngFor="let item of ardene.section1.items"

NgFor only supports binding to Iterables such as Arrays. If you want to iterate over an object, you can make use of KeyValuePipe which

Transforms Object or Map into an array of key value pairs.

Looking at your data structure I don't see any reason for you to use *ngFor, you can simply access the object properties as:

{{ardene?.section1?.items?.img}}
{{ardene?.section1?.items?.name}}
{{ardene?.section1?.items?.description}}

If you want to avoid repetition of ardene?.section1?.items, you can try to do something as below:

<ng-container *ngIf="ardene?.section1?.items as item">
  <img  src=`{{ardene.assetPath}}{{item?.img}}`>
  <div>
    <h5 >{{item?.name}}</h5>
    <h6 >{{item?.description}}<br></h6>
    <a>
      <h6 >Shop Now</h6>
    </a>
  </div>
</ng-container>

CodePudding user response:

Code wise it looks fine. The way you access {{ardene.assetPath}} kind of looks off. If subscription really does return some items for you then syntax should go something more like this:

<div >
BEFORE FOR LOOP
<div  *ngFor="let master of ardene | keyvalue">
<ng-container *ngFor="let item of master.section1.items">
    INSIDE FOR LOOP
    <img  
        src=`{{master.assetPath.value}}{{item.img.value}}`>
    <div>
        <h5 >{{item.name.value}}</h5>
        <h6 >{{item.description.value}}<br></h6>
        <a>
            <h6 >Shop Now</h6>
        </a>
    </div>

</ng-container>
</div> 
  •  Tags:  
  • Related