Integrating another observable library with canjs symbols

xposted from gitter, I figured this would be a more appropriate place to discuss…

Hi guys, I’ve got a side project I’ve dabbled with in the past and would like to try integrating more tightly with Canjs. Its using Openlayers - a sort of observable mapping library. It has these observable list-like objects called collections, and I’m having issues getting it to work with canjs templates for of, each, etc.

Can anyone lend any tips? Here’s the main file where I am adding canjs symbols to the list-like element: https://github.com/roemhildtg/can-ol-symbol/blob/master/lib/assignCanListSymbols.js

There’s also a basic demo that can be ran with steal/http-server here: https://github.com/roemhildtg/can-ol-symbol/blob/master/index.html

I’ll take a look. https://canjs.com/doc/can-diff/patcher/patcher.html is what is used to make {{#each}} and {{#for}} work. An integration test with that would probably be more direct.

anyway you can write up more info? What isn’t working?

Also a link to the gitter thread would help.

I just copied the entire topic from gitter, I didn’t get any responses yet so that’s why its so short.

Specifically, what’s not working is using for of on an object that is an ol.collection type. This specific type has a getArray method which returns an array of the objects. It also has a .length property and dispatches events like change:length. It also has some of the array-like methods like, push, pop.

<!-- my code does this, but updates are not reflected --> 
{{#for(layer of map.layergroup.layers)}}<li>{{layer.title}}</li>{{/for}}

To try and work with this, I’ve implemented the can.value symbol and can.onValue…but neither seem to be working. I’ll look into using can-diff patcher directly.

Anyway you can create a small example that does something very basic like:

var layers = MAKE_YOUR_TYPE();
var view = stache(` {{#for(layer of map.layergroup.layers)}}<li>{{layer.title}}<li>{{/for}}`;

var frag = view({
 layers: layers
});

document.body.appendChild(frag);

layers.ADD_STUFF({title: "thing"})

I saw that index.html is doing something similar, but I also see some images and such in there. The more simple, the better. Thanks!

(btw, you might need to support can.patches for diffing to work): https://canjs.com/doc/can-reflect/observe.onPatches.html

If you are implementing observability yourself, you might checkout can-key-tree or https://canjs.com/doc/can-event-queue/map/map.html which will add a lot of the methods you need … you just need to dispatch like observable[canSymbol.for("can.dispatch")]("prop",[2,1]);

Okay sounds good. Thanks for all the suggestions, I’ll look into this a bit more next time I work on this!

Okay. I updated that example with a much simpler sample. I’ve also implemented on/off patches, but neither of them are actually getting called right now…

Anyways, here’s the updated sample.

console prints:

getKeyValue 0
assignCanSymbols.js:46 onKeyValue 0
assignCanSymbols.js:46 onKeyValue length

It looks like canjs is trying to observe the length key and the 0 key. But nothing more so far. What’s next? :slight_smile:

Okay, I made some progress. I have it (mostly) working, I had to add a length getter. I feel like this is oddly specific though, not every “list-like” observable has a length property. Shouldn’t canjs be using the can.size symbol to look this up?