Angular 2+...would i need *ngFor for this?

Hello - I am playing with an input box with typeahead/completer style functionality in Angular 2+. Its been set up so that a user starts typing...the completer suggests items based on what is being entered...and the user clicks on the selection they want.

What they have selected from the completer drives what is displayed in a table. All that is working fine.

What I am not sure how to do is...if the item they select should have multiple rows in the table...lets say if the completer is searching a list of customers to display orders...but the customer they select has multiple orders.

*ngFor is not working for me...because I get an error telling me it can only be used with an array.

The way things are set up with the completer...i have this code in the component.ts file setting the selected item. It looks in a users array, and sets the item selected to selectedUser.

   protected onCompleterSelect(item: CompleterItem) {
   console.log(item)
   if (item && item.originalObject) {
     console.log(this.users.find(user => user.ID === item.originalObject.ID))
     this.selectedUser = this.users.find(user => user.ID === item.originalObject.ID) ;
    
  }

}

Open in new window


Then in my html file the table is being built based on the selected user.

<table class="table">


   <th rowspan="1" colspan="4" >
     PERSONAL INFORMATION

   </th>
   <tr>
     <td>ID</td><td>{{selectedUser && selectedUser.ID || " " }}</td>
     <td>Name</td><td>{{selectedUser && selectedUser.Name || " " }}</td>
     
   </tr>
  

   </table>

Open in new window



When i try to add an ng-container  with *ngFor...it complains the ngFor needs an array...which because the "selectedUser" is being set in the componet.ts file...where its looking through the array there and specifing the selectedUser based on what the user clicks on when using the completer. ...its not happy.

I have tried a handful of ways to use the *ngFor  ...but it does not work.

Some of the items I have tried are
<ng-container *ngFor="let selectedUser of users">

Open in new window


or
<ng-container *ngFor="let x of selectedUser">

Open in new window


and a handful of other variations...but it is not happy.

Is there another looping command similar to ngFor i can use to have it loop through and display all records for the "selectedUser"...

or is there something i can do in the ngFor to make it loop through and display the records matching the ID of the selectedUser?

Or...is the if statement in my component.ts set up incorrectly for the functionality i have described?

The reason i am not just using a pipe for this...is I do not want anything to display in the table until the user selects a value from the completer input.

I am still really new to Angular and kind of just learning as i go so any tips are appreciated.

Thanks,
Cynthia HillLead ConsultantAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
Why not return your selected user in an array
this.selectedUser =[];
this.selectedUser.push(this.users.find(user => user.ID === item.originalObject.ID) );

Open in new window

0
Cynthia HillLead ConsultantAuthor Commented:
Hey Julian  -

Thanks for pointing me in that direction.

Its still just returning the 1st row. I applied the code you suggested to the if in the component.

protected onCompleterSelect(item: CompleterItem) {
   console.log(item)
   if (item && item.originalObject) {
     this.selectedUser =[];
     this.selectedUser.push(this.users.find(user => user.ID === item.originalObject.ID) );

     }

}

Open in new window


I added an ngFor...which isn't causing an error any more but still only returns the 1 row...

  <table class="table">

           <tr>
               <th>Report Date</th>
               <th>ID</th>
               <th>Name</th>
            </tr>

        <ng-container *ngFor="let se of selectedUser">
       
     <tr>
       <td>{{se && se.ReportDate || " " }}</td>
       <td>{{se && se.ID || " " }}</td>
       <td>{{se && se.Name || " " }}</td>
     </tr> 

 </ng-container >

          </table>

Open in new window


Any other tips of items I can try?
0
Julian HansenCommented:
The suggestion was to fix the error for ngFor (which expects an array)

If you want to return all records that match a criteria use filter() - it will return an array of all records that match.

If you use filter though you won't need my solution using the push you can just return the filtered array

protected onCompleterSelect(item: CompleterItem) {
   console.log(item)
   if (item && item.originalObject) {
     this.selectedUser = this.users.filter(user => user.ID === item.originalObject.ID);
     }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cynthia HillLead ConsultantAuthor Commented:
Alright Jullian - You are officially my favorite person of the day! The filter did what I needed.

Greatly appreciate your assistance!!
0
Julian HansenCommented:
You are welcome.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.