0

I'm programming with angular 1.6 and typescript. In my project i need to load list of users from the server and display the list with checkboxes near each person:

 <div class="container">
  <h2>Hello {{ $ctrl.name }}</h2>
  <ul ng-repeat="user in $ctrl.users"  class="list-group">
    <li class="list-group-item">
      <input type="checkbox" ng-model="user.selected">
      {{user.name}}
    </li>
  </ul>
  <button class="btn btn-primary" ng-click="$ctrl.showSelected()">save</button>
</div>

After user selects some persons and clicks the button below he should get alert with list of selected persons.

Here is Person object that comes from server

export class Person {
    public name:string; 
}

And my Service looks this way:

getUsers() : ng.IHttpPromise<Person[]> {
 return this.$http.get('users.json').then((res:ng.IHttpPromiseCallbackArg<Person[]>)=>{
  return res.data
 })
}

Since in my ui the person elements must have "selected" property - i thinking about create uiPerson class which will derive from Person:

import { UsersService } from './service'
import { Person } from './Person'
  class uiPerson extends Person{
  public selected:false;
}
export const AppComponent = {
  template: `
  <div class="container">
  <h2>Hello {{ $ctrl.name }}</h2>
  <ul ng-repeat="user in $ctrl.users"  class="list-group">
    <li class="list-group-item">
      <input type="checkbox" ng-model="user.selected">
      {{user.name}}
    </li>
  </ul>
  <button class="btn btn-primary" ng-    click="$ctrl.showSelected()">save</button>
</div>
`,
 controller: class AppComponent {
 static $inject =["usersService"]
 constructor(private usersService: UsersService) {  }

 $onInit() {
   this.name ='Users';
   this.usersService.getUsers().then(users=>{
     this.users= users as uiPerson[];//<-- HERE IS QUESTION
   }) 
  }
   showSelected() {
     alert(this.users.filter(u=>u.selected).map(u=>u.name).join(','))
   }
}
 };

I'm new with typescript - am i right about mapping with "this.users= users as uiPerson[]" syntax? Is there some more correct way to do it?

here is the plnkr

Thanks

2 Answers 2

2

This looks reasonable to me. I would personally make a couple adjustments:

  • Make Person and UiPerson interfaces instead of classes, unless you plan to use them in different ways in the future (such as constructing them with new)
  • Consider whether it makes sense for selected to be optional, since at first your array of UiPerson objects will not have it defined. That may also allow you to skip the type cast.

Here is a revised plunkr with those changes, and I also took the liberty to make it closer to my personal style, in case you like what you see.

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

2 Comments

Excellent advice here.
Hi, can you please paste some code which shows the differences?
1

My advice here would be to avoid introducing the uiPerson class - it is adding complexity and polluting your domain model. Is 'selected' truly an attribute of a Person?

What would happen if you were required to present the same Person is two lists?

public selectedList1: boolean;
public selectedList2: boolean;

Instead - I would look to store the 'selected' state in your Controller, exposing a simple 'isSelected' function:

controller: class AppComponent {
    static $inject =["usersService"]
    constructor(private usersService: UsersService) {  }

public selectedUsers: Person[] = [];

$onInit() {
    this.name ='Users';
    this.usersService.getUsers().then(users=>{
        this.users= users; <-- No uiPerson
    }) 
}

showSelected() {
    alert(this.selectedUsers.map(u=>u.name).join(','))
}

isSelected(person: Person): boolean {
    return selectedUsers.indexOf(person) !== -1;
}

Template:

<input type="checkbox" ng-checked="$ctrl.isSelected(user)">

Plnkr

1 Comment

Thanks a lot for your answer, i had tough time to decide which to mark as "answer", and may be i was wrong

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.