0
votes

I have an Angular 6 component that fetches an observable list of users and then displays a table of the users using the *ngFor statement. Each row I have included a submit button that calls a function in the component ts file passing in the user for that row. This is working as expected so far.

Now I want to add a select option to each row with a list of actions the user wants to perform. How do I get the value of the selected action for the correct row?

Here is what I have so far.

-Sample JSON object returned from http call.

[
  {
    "userId": 1,
    "username": "user1",
    "firstName": "f1",
    "lastName": "l1",
    "active": true
  },
  {
    "userId": 2,
    "username": "user2",
    "firstName": "f2",
    "lastName": "l2",
    "active": true
  }
]

In the component.ts I subscribe a property of type UserSearchModel[] to the json response and also created a function for the table to call.

users$: UserSearchModel[];

submituseraction(user: UserSearchModel) {
    console.log(user.userId);
  }

Here is the model.

export class UserSearchModel {
    userId: number;
    username: string;
    firstName: string;
    lastName: string;
    active: boolean;   
}

In the html I have the following tr for displaying and submitting the data.

  <tr *ngFor="let user of users$">
    <td>{{ user.username}}</td>
    <td style="word-break: break-all">{{ user.firstName }}</td>
    <td style="word-break: break-all">{{ user.lastName }}</td>
    <td>{{ user.active }}</td>
    <td class="text-nowrap">
      <select name="usersearchactions" id="usersearchactions" title="Actions">
        <option value="0">Update User Info</option>
        <option value="1">Update Email</option>
        <option value="2">Reset Password</option>
        <option value="3">Notification Settings</option>
        <option value="11">Research</option>
      </select>
      <button (click)="submituseraction(user)" class="btn btn-primary btn-xs" type="submit">GO!</button>
    </td>
  </tr>

So far everything is great. I pull the list of users and properly display them. Each row will also have a drop down to select the action to perform on the user. I also get the correct user in my submituseraction method. The only problem I have is how do I get the selected action for that user in my submituseraction method? I was hoping there was an easy way to get that value without much change.

I did try to update the UserSearchModel to include a new UserAction[] that is populated with my list and display it with the *ngfor command so that I can just grab that off the user object passed to the function. This does not work as the UserAction[] is undefined after populating the data in the subscribe event. I even tried to make it readonly and populate in the constructor with no luck. Both ways I end up with an undefined UserAction[] so now there isn't any actions populated in the select.

    export class UserSearchModel {
        userId: number;
        username: string;
        firstName: string;
        lastName: string;
        active: boolean;
        userActions: UserAction[] = [
                { id: 0, name: "Update User Info" },
                { id: 1, name: "Update Email" },
                { id: 2, name: "Reset Password" },
                { id: 3, name: "Notification Settings" },
                { id: 4, name: "Patient Access Requests" },
                { id: 11, name: "Research" }
            ]
    }


    export class UserAction {
        id: number;
        name: string;
    }

<select name="userActions" id="userActions" title="Actions">
    <option *ngFor="let action of user.userActions" [value]="action"> 
        {{action.name}}</option>
      </select>

I wasn't a big fan of changing the model but even this didn't work.

Any help/direction/guidance would be much appreciated. Also, I am just starting out in Angular (probably obvious by the question) but if you see anything else that is obviously wrong with this please let me know.

Thanks.

1
I failed finding the observable. Where do you use it? The $ in the end of the variable name indicates that object is an observable, but you defined it as an array of objectsCristian Traìna
I left out the code subscribing to a service to keep it focused. I only included that it was an observable in case that mattered in the solution.user1041169

1 Answers

3
votes

Add an angular variable declaration (#foo) to the select tag and pass in its value to submituseraction along with user.

<select #actions name="usersearchactions" id="usersearchactions" title="Actions">
  <option value="0">Update User Info</option>
  <option value="1">Update Email</option>
  <option value="2">Reset Password</option>
  <option value="3">Notification Settings</option>
  <option value="11">Research</option>
</select>
<button (click)="submituseraction(user, actions.value)" class="btn btn-primary btn-xs" type="submit">GO!</button>