0

I am using NGX-Chips in Angular. I am saving the typed in chips into Firebase and retrieving them.

Problem is, when it tries to render the saved chips, it can't and throws an error.

Before posting this question, I tried to read through and follow this issue on GitHub and added the displayBy and identifyBy tag with no avail.

THE ERROR

Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

HTML Code

<tag-input 
     (onAdd)="onCategoryAdded($event, product.external_id)" 
    [displayBy]="'display'"
    [identifyBy]="'$key'" 
    [(ngModel)]="product.categories"
    [ngModelOptions]="{standalone: true}"
    theme="minimal" 
    placeholder="Categories"
>
 <tag-input-dropdown [autocompleteItems]="categories"></tag-input-dropdown></tag-input>
</tag-input>

In my controller, I set an observable item, listen for value changes and assign those to mentioned observable.

public products: Observable<any[]>;

ngOnInit() {
   this.products = this.afd.list('/products').valueChanges();
}

onCategoryAdded(event, product) {
  this.afd.database.ref('/products').orderByChild('external_id').equalTo(product).once('value', (snapshot) => {
    snapshot.forEach((product) => {
      this.afd.database.ref('/products').child(product.key).child('categories').push({
        'display' : event.display,
        'value' : event.value
      });
    });
  });
}

product.categories prints out like below when I add {{product.categories | json}} to my html.

{ "-LfN8VhSrWBye-8ukSAq": { "display": "Featured", "value": "Featured" } }

Should I alter how I save the categories in Firebase so it returns a different value or should I transform the returned value somehow within the controller?

Mitch Evans
  • 301
  • 4
  • 17

1 Answers1

0

Just as described in the error NGX-CHIPS is waiting for an array and you are passing an object

Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

You are passing this to NGX-CHIPS


{ "-LfN8VhSrWBye-8ukSAq": { "display": "Featured", "value": "Featured" } }

you need to convert this json/object to an array you can do that using the map operator

// don't forget to import the operator

import { map } from 'rxjs/operators'


ngOnInit() {
   this.products = this.afd.list('/products').valueChanges().pipe(
map(list => {

      const productsArray = Object.keys(list).map(key => {
         const item = list[id]; // [{display: 'Featured', value: 'Featured'}]
         item.key = key;  // [{key: "-LfN8VhSrWBye-8ukSAq", display: 'Featured', value: 'Featured'}]
         return item;
      });

   }));
}


SaMiCoOo
  • 327
  • 2
  • 10
  • Where is `id` defined in `list[id]`. Also this manipulates the entire products array. The categories are a child of the product. – Mitch Evans May 21 '19 at 02:47
  • Any ideas on how we could filter just that object for each product? – Mitch Evans May 23 '19 at 16:44
  • Firebase does not return an array it returns an object, so if you want to iterate through them you will have to convert that object to an array. Like what I did in my answer. But you still need an identifier to be able to reference the document when you update it, that is why I took each object key and added into every object inside that array – SaMiCoOo May 23 '19 at 17:47