# Change even on map

**URL:** <https://forums.bitovi.com/t/change-even-on-map/482>\
**Category:** CanJS\
**Created:** [November 30, 2016, 8:12pm UTC](https://forums.bitovi.com/t/change-even-on-map/482 "2016-11-30T20:12:57Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![fp\_dev](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@fp\_dev](https://forums.bitovi.com/u/fp_dev)\
**Post date:** [November 30, 2016, 8:12pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/1 "2016-11-30T20:12:57Z")

</div>

When having a Map value with attributes whose value is an object, is there a way to bind a change event on it, without using a compute attribute?

for instance, having a map like this, check when data1 changes…

```
var newData = can.DefineMap.extend({
  "data1":{
    value:false
  },
  "data2":{
    value:false
  }
})

var vm = can.DefineMap.extend({
    "temp":{
      value: newData
    }
});

var myvm = new vm({});

myvm.on("temp.data1",function(){});

```

[JS EXAMPLE](http://jsbin.com/gisixahoxo/1/edit?html,js,console,output)

---

<div class="post-metadata">

**Author:** ![chasen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.bitovi.com/chasen/32/402_2.png) [@chasen](https://forums.bitovi.com/u/chasen)\
**Post date:** [November 30, 2016, 9:05pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/2 "2016-11-30T21:05:07Z")

</div>

I would do this:

```auto
var temp = myvm.temp;
temp.on("data1", function(event, newVal, oldVal) {
  console.log("CHANGED TEMP");
});

```

Would that work for your code?

---

<div class="post-metadata">

**Author:** ![justinbmeyer](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.bitovi.com/justinbmeyer/32/179_2.png) [@justinbmeyer](https://forums.bitovi.com/u/justinbmeyer)\
**Post date:** [November 30, 2016, 10:43pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/3 "2016-11-30T22:43:35Z")

</div>

@chasen that won’t detect when the `.temp` property changes.

@fp_dev you should use either a computed property or a compute.

BTW, it’s a good idea to capitalize construtor functions `NewData` instead of `newData`.

---

<div class="post-metadata">

**Author:** ![fp\_dev](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@fp\_dev](https://forums.bitovi.com/u/fp_dev)\
**Post date:** [December 1, 2016, 8:06am UTC](https://forums.bitovi.com/t/change-even-on-map/482/4 "2016-12-01T08:06:21Z")

</div>

Thank you both!

I used the compute property in the JS EXAMPLE. But what if the VM is the one of a Component? should I use the event like the following?

```
//with Can@3.X
    Component.extend({
       tag: "my-cmp-tag",
       view: my_stache_template,
       viewModel: NewData,
       events: {
           "{scope} temp.data1": function(obj,ev,new, old){ .... }
       }
    });
```

---

<div class="post-metadata">

**Author:** ![justinbmeyer](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.bitovi.com/justinbmeyer/32/179_2.png) [@justinbmeyer](https://forums.bitovi.com/u/justinbmeyer)\
**Post date:** [December 1, 2016, 2:51pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/5 "2016-12-01T14:51:30Z")

</div>

you should avoid the `events` object generally speaking.

---

<div class="post-metadata">

**Author:** ![fp\_dev](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@fp\_dev](https://forums.bitovi.com/u/fp_dev)\
**Post date:** [December 1, 2016, 4:21pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/6 "2016-12-01T16:21:43Z")

</div>

I do not mean to bother you but do you mean in the Component object? Or I should design my application to just get/set properties and use the live-binding?  
But if I need to call function/methods to initialize external objects I don’t see any other way.

Thanks for this exchange of ideas: it very helpful for me.

---

<div class="post-metadata">

**Author:** ![justinbmeyer](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.bitovi.com/justinbmeyer/32/179_2.png) [@justinbmeyer](https://forums.bitovi.com/u/justinbmeyer)\
**Post date:** [December 1, 2016, 4:45pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/7 "2016-12-01T16:45:02Z")

</div>

Ideally your application is just getters and methods and lets live-binding do all the work.

Yes, sometimes this breaks down and that’s why the Comonent’s `events` object is there. In Bitballs, we use it to work with a Youtube video. But if possible, it’s best to avoid the events object.

What external objects do you need to initialize?

---

<div class="post-metadata">

**Author:** ![fp\_dev](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@fp\_dev](https://forums.bitovi.com/u/fp_dev)\
**Post date:** [December 1, 2016, 7:07pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/8 "2016-12-01T19:07:51Z")

</div>

For instance I have a class that init a Google Map with a list of markers.  
This GoogleMap is initialized when the user click on a link that will handle the display of the Component.  
In this case I need to wait the Component is created (it’s tag in the stache template filled) and then init the google Map using the `event inserted of the Component.

```
// Map that init the main page
var status = can.Map.extend({
  showMap:{
     value:false
  },
  setShowMap: function(val){
      this.showMap = val;
  }
})

//can stache template of the main page
<button ($click)="setShowMap(true)">show map</button>
{{#if showMap}}
<can-import from="component/googleMap/googleMap" >
  {{#if isResolved}}
    <map></map>
</can-import>
{{/if}}

```

Here is the pseudo-code of the component

```
// component/googleMap/googleMap.js
import stache from "can-stache";
import Map from "can/define/map/map";
var mapStatus = Map.extend({
     mapInstance:{
             value: null;
     }
});

Component.extend({
   tag: "map",
   view: stache("<div id="locationMap"></div> <div id="mapSearchPanel> .. </div>"),
   viewModel: mapStatus,
   events:{
        inserted: function(){
                    this.viewModel.mapIntance = createMap.getInstance('locationMap');        
        }
   }
})

```

**createMap.getInstance(div\_id)** is a Singleton class that will return the instance of the map in the div\_id position of the DOM.

---

<div class="post-metadata">

**Author:** ![chasen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.bitovi.com/chasen/32/402_2.png) [@chasen](https://forums.bitovi.com/u/chasen)\
**Post date:** [December 12, 2016, 9:53pm UTC](https://forums.bitovi.com/t/change-even-on-map/482/9 "2016-12-12T21:53:04Z")

</div>

@fp_dev, that example looks like it would work: once the `map`[1] component is `inserted`, you can load the map into `#locationMap`.

If you’re trying to access `mapInstance` in the parent scope after the component has been inserted, you can use the [`{^to-parent}`](http://canjs.com/doc/can-stache-bindings.toParent.html# __child_prop___ key_) binding.

[1] Just FYI, your components should have a hyphen in them, so `app-name` or something like that.
