9

How i can use two-way binding on Map objects?

The following code doesn't work as expected:

Component:

@Component({
    moduleId:    module.id,
    selector:    "my-component",
    templateUrl: "my-component.html",
    styleUrls:   ["my-component.scss"],
})
export class MyComponent {
    myMap: Map<string, Object> = Map<string, Object>()
        .set('first', {text: 'abc'})
        .set('second', {text: 'foo'})
    ;
}

Template:

<div class="items" *ngFor="let item of myMap.values()">
    <input type="text" [(ngModel)]="item.text" />
</div>
3
  • what do you mean when you say "doesn't work as expected'? Commented May 2, 2017 at 9:40
  • Map<string, Object> is this valid data structure of angularjs2? Commented May 2, 2017 at 10:11
  • It doesn't bind value changes to page. With array of Objects it's work, but not with Maps. Commented May 3, 2017 at 1:03

1 Answer 1

3

Actually in this example two-way data binding works as expected. Probably your mistake is in creating Map object:

myMap: Map<string, Object> = Map<string, Object>()

You have to include new keyword before Map (because Map Constructor is not callable):

myMap: Map<string, Object> = new Map<string, Object>()
        .set('first', {text: 'abc'})
        .set('second', {text: 'foo'})

And now everything works as expected. You can check this stackblitz demo as well.

Notice: According to this Angular issue on GitHub: Maps have no orders in keys and hence they iteration is unpredictable. This was supported in ng1, but we think it was a mistake and will not be supported in NG2.

One of the simplest solutions for this - is to use Array.from() method on myMap.entries():

getEntities() {
  // this will return [['first', { text: 'abc' }], ... ]
  // and after mapping we get [{ text: 'abc' }, ...]
  return Array.from(this.myMap.entries()).map(item => item[1]);
}

And now we can use it in the template:

<div class="items" *ngFor="let item of getEntities()">
  <input type="text" [(ngModel)]="item.text" />
</div>

In this example two-way data-binding works as well.

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

Comments

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.