These are chat archives for canjs/canjs

18th
Feb 2018
Dovid Bleier
@dbleier
Feb 18 2018 20:44
I hope somebody is listening on a Sunday
I am working in can4, and wired my prop to a can-connect model (base-map) using a fixture
when I run the app it loads the data as expected, the problem is my test cases are now choking
getting a resolve is not a function error
here is the prop on the DefineMap
    available: {
        get: function(lastSet, resolve) {
            if (lastSet) {
                return lastSet;
            }

            return Unit.getList({}).then((units) => {
                return resolve(units);
            });
        }
    },
here is the test
QUnit.test('Test Select', function(assert) {
    var vm = new ViewModel(),
        done = assert.async(8);
    vm.available.then(function(units) {
        units = units.serialize();
        vm.select(2);
        assert.deepEqual(vm.selected.serialize(), [units[2]], '3rd item selected');
        assert.ok(vm.available[2].selected, '3rd available item maked selected');
        vm.select(7);
        assert.deepEqual(vm.selected.serialize(), [units[7]], '8th item selected');
        assert.ok(vm.available[7].selected, '8th available item marked selected');
        assert.notOk(vm.available[2].selected, '3rd available item marked unselected');
        vm.select(4);
        assert.deepEqual(vm.selected.serialize(), [units[4]], '5th item selected');
        assert.ok(vm.available[4].selected, '5th available item marked selected');
        assert.notOk(vm.available[7].selected, '8th available item marked unselected');
        done();
    });
});
what am I missing?
Frank Lemanschik
@frank-dspeed
Feb 18 2018 20:50
@dbleier i am not sure if the interface is the right
that your using
get: function(lastSet, resolve) {
Dovid Bleier
@dbleier
Feb 18 2018 20:51
ok, what do you suggest? Sadly, the docs are quite lacking on this
Frank Lemanschik
@frank-dspeed
Feb 18 2018 20:51
first of all i will need to look what base-map is
it is some kind of prefined define-map
i my self use always define/map/map
Frank Lemanschik
@frank-dspeed
Feb 18 2018 20:52
aj
base-map has nothing to do with your sitiation as far as i see
try the following
replace that get: function(lastSet, resolve) {
with
        value: function({ lastSet ,resolve, listenTo }) {
its importent to point out the {}
inside the function()
this function recives a prop with porp.lastSet prop.resolve ...
{} this is expanding it to the single values
so the rest of the code should work out of the box
Dovid Bleier
@dbleier
Feb 18 2018 20:57
ok, trying it
Frank Lemanschik
@frank-dspeed
Feb 18 2018 20:57
its the new streaming value
Streaming Property Definitions
This might be what I'm most excited about in CanJS 4.0. There seems to be a gap between object-oriented state mechanics like those found in Vuejs, CanJS, MobX and the reducer/streaming patterns in Angular with RXJS and Redux. can-define's improved value behavior aims to fill that gap. Use it to create code that is easier to understand and debug.

How a stateful value behaves should be clearly defined and located in one place. In CanJS 3.0, one often resorted to using setters or component's events object to implement property behaviors that were not definable with getters alone.

Streaming Property Definitions
This might be what I'm most excited about in CanJS 4.0. There seems to be a gap between object-oriented state mechanics like those found in Vuejs, CanJS, MobX and the reducer/streaming patterns in Angular with RXJS and Redux. can-define's improved value behavior aims to fill that gap. Use it to create code that is easier to understand and debug.

How a stateful value behaves should be clearly defined and located in one place. In CanJS 3.0, one often resorted to using setters or component's events object to implement property behaviors that were not definable with getters alone.

Dovid Bleier
@dbleier
Feb 18 2018 20:58
I saw that in the blog
Frank Lemanschik
@frank-dspeed
Feb 18 2018 20:59
i think the default getter now don't has the resolve any more
Dovid Bleier
@dbleier
Feb 18 2018 20:59
it does when coming from stache
btw, switched to valueand still getting the resolve undefined
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:00
hmmm i will look maybe i am missing something
simply
reduce my example with {}
to value function(prop)
Dovid Bleier
@dbleier
Feb 18 2018 21:00

what do you mean?

ok

Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:00
and console.log(prop)
paste that here pleace
Dovid Bleier
@dbleier
Feb 18 2018 21:02
undefined
    available: {
        value: function({ prop }) {
            // if (lastSet) {
            //     return lastSet;
            // }
            console.log(prop);
            return Unit.getList({}).then((units) => {
                return resolve(units);
            });
        }
    },
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:02
remove the {}
Dovid Bleier
@dbleier
Feb 18 2018 21:02
ok
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:02
so that it is normal function that gets prop
{} === expansion so it will do for you stuff like resolve = prop.resolve lastSet = prop.lastSet
Dovid Bleier
@dbleier
Feb 18 2018 21:03
Object {resolve: , listenTo: , stopListening: , lastSet: SimpleObservable}
unit-selector.js:14
lastSet:SimpleObservable {value: undefined, Symbol(can.getName): }
listenTo:function () { … }
resolve:function () { … }
stopListening:function () { … }
proto:Object {constructor: , defineGetter: , defineSetter: , …}
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:03
look its there
we see it
Dovid Bleier
@dbleier
Feb 18 2018 21:03
Object {resolve: , listenTo: , stopListening: , lastSet: SimpleObservable}
unit-selector.js:14
lastSet:SimpleObservable {value: undefined, Symbol(can.getName): }
listenTo:function () { … }
resolve:function () { … }
stopListening:function () { … }
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:03
now use in your code prop.resolve
prop.lastSet
Dovid Bleier
@dbleier
Feb 18 2018 21:04
yeah, now I see it
ok, let me try that
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:04
maybe your javascript environment did not support expansion
oh and 2 more importent things
never return resolve!
simply call resolve but not return
and also add under value: the Type: Unit.List
that will help to prevent from binding issues if you plan to map that into other components
that are setting values
Kevin Phillips
@phillipskevin
Feb 18 2018 21:07
@dbleier you need to bind on the property for resolve to be defiend
vm.on('prop', function(){});
Dovid Bleier
@dbleier
Feb 18 2018 21:08
yeah, how do you do that?
I tried that, but then it returns null in the then
anyway I tried @frank-dspeed value solution
but now that code doesn't even get called in my test
and in the actual app I lost the available.isPending in the stache, so it is now trying to call methods that depend on available being resolved before it is
what causes the value function to fire?
or is my test case not set up correctly?
Kevin Phillips
@phillipskevin
Feb 18 2018 21:13
You can go back to your original async getter
That is still supported
But don't return the promise
If you need the promise also then split it into two properties
Dovid Bleier
@dbleier
Feb 18 2018 21:14
I tried that but then the promise never registers as resolved
Two issues here
  1. getting the test case to execute properly
  1. in the actual app, only displaying the section of the template that handles the returned data after it returns
Kevin Phillips
@phillipskevin
Feb 18 2018 21:16
As soon as you call resolve, your property is no longer a promise
It becomes whatever you resolved with
Dovid Bleier
@dbleier
Feb 18 2018 21:16
using value or get?
that's what I thought, but it wasn't happening
also using get was creating a resolve function which is why I tried @frank-dspeed value solution
I think you want something like that
One property for gamePromise, a separate property for game
gamePromise always has the promise, so you can use isResolved
Dovid Bleier
@dbleier
Feb 18 2018 21:20
isn't that using can3?
Kevin Phillips
@phillipskevin
Feb 18 2018 21:20
Sure, but it doesn't matter
Nothing changed there
Dovid Bleier
@dbleier
Feb 18 2018 21:21
so than what is the can4 value prop meant to do?
Kevin Phillips
@phillipskevin
Feb 18 2018 21:21
value is more useful when you need to depend on
Change events of other properties
Dovid Bleier
@dbleier
Feb 18 2018 21:22
ok
so I just tried this:
    unitsPromise: {
        get: function() {
            return Unit.getList({});
        }

    },
    available: {
        get: function(lastSet, resolve) {
            if (lastSet) {
                return lastSet;
            }

            this.unitsPromise.then((units) => {
                resolve(units);
            });
        }
    },
and am gettting resolved is not a function in my test
again
Kevin Phillips
@phillipskevin
Feb 18 2018 21:24
You need to bind on the property
vm.on('available', function(){});
Dovid Bleier
@dbleier
Feb 18 2018 21:25
ok
also in stache I have
{{#if(unitsPromise.isPending)}}
Loading Units... 
{{else}}
but it is ignoring the isPending and is rendering the else
Kevin Phillips
@phillipskevin
Feb 18 2018 21:28
How about if you do
{{#if unitsPromise.isPending}}
Could be a bug
Or if you're using a fall-through cache it won't be pending very long
Dovid Bleier
@dbleier
Feb 18 2018 21:30
nope, still calling the dependent method before promise is resolved
Kevin Phillips
@phillipskevin
Feb 18 2018 21:30
It will resolve ri
Right away with the cached data
Dovid Bleier
@dbleier
Feb 18 2018 21:31
not using fall-through-cache because I don't want cached data, but right now am using fixture with 500ms delay
in my test I now have
    vm.on('available', function() {});
    vm.unitsPromise.then(function(units) {
but it never calls the then callback
I also tried vm.available.then(... also doesn't work
Kevin Phillips
@phillipskevin
Feb 18 2018 21:33
What happens? Does your test time out?
Dovid Bleier
@dbleier
Feb 18 2018 21:35
it just hangs,
I tried putting the then callback as the .on callback
now it resolves
but not with the data
Kevin Phillips
@phillipskevin
Feb 18 2018 21:36
Are you sure your fixture is working?
Make sure you don't see the actual ajax call in the network tab
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:38

@phillipskevin

not using fall-through-cache because I don't want cached data, but right now am using fixture with 500ms delay

shouldn't the ajax request happen then?
Dovid Bleier
@dbleier
Feb 18 2018 21:38
yes
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:38
even if it goes to fixture
Dovid Bleier
@dbleier
Feb 18 2018 21:38
but I think I got it, almost
Kevin Phillips
@phillipskevin
Feb 18 2018 21:38
No
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:38
and not return without it
Dovid Bleier
@dbleier
Feb 18 2018 21:38
was only passing in 1 param to the on callback
Kevin Phillips
@phillipskevin
Feb 18 2018 21:39
Ah I think the first param is the vm
Why does that matter though?
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:40
@phillipskevin is that documented with the value behavior that you need to bind to it to become resolve? sounds a bit like lazy value
Kevin Phillips
@phillipskevin
Feb 18 2018 21:41
It is, yes
Dovid Bleier
@dbleier
Feb 18 2018 21:42
yeah, but a good example how to do this is lacking
Kevin Phillips
@phillipskevin
Feb 18 2018 21:42
Yeah, you're right
Dovid Bleier
@dbleier
Feb 18 2018 21:43
ok, test case is working now
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:43
i think we could maybe do more examples for define maps probally with some examples
like how to use a promise and how to use value stream and all that all in one place some thing like a cheat sheet
Dovid Bleier
@dbleier
Feb 18 2018 21:44
but it is still ignoring the unitsPromise.isPending
Kevin Phillips
@phillipskevin
Feb 18 2018 21:44
Yeah, there's always room for more examples
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:44
how do you set unitPromise ?
 default() => Unit.getList(),
ups
without the return if you use one line
Dovid Bleier
@dbleier
Feb 18 2018 21:45
I think an example wiring a can-component up to can-connect and rendering in a stache template when resolved would be helpful and how the test case should be written
should be default and not get?
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:46
yes i was last day and today working on something like that
as i researched for ways to make it more understandable and easy
but i think its at present a good way to use the existing implamentation after all
but we should write a single page what exactly happens in the case of superMap as example
Kevin Phillips
@phillipskevin
Feb 18 2018 21:46
get should work fine
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:47
i am always using a function to return the promise
Kevin Phillips
@phillipskevin
Feb 18 2018 21:47
If you can reproduce in a jsbin that would help a lot
We can investigate
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:47
i have best results with that kevin doesn't get values get diffrent handled
then a function that returns a value?
i remember there was a good reason to use a function to return the promise
and not set the promise directly
Dovid Bleier
@dbleier
Feb 18 2018 21:48
still not working
ok
let me see if I can set one up
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:49
then as kevin pointed out try to make a jsbin if possible cool
but you can also fast try
to use default()=>
Kevin Phillips
@phillipskevin
Feb 18 2018 21:49
get would set up bindings if you were using any observables
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:49
i am using that in all my canjs4 apps
Kevin Phillips
@phillipskevin
Feb 18 2018 21:49
But you're not
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:49
and it working
Kevin Phillips
@phillipskevin
Feb 18 2018 21:49
So it's the same
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:50
ok your word in gods ears :)
Dovid Bleier
@dbleier
Feb 18 2018 21:50
I tried default, no diff
what should I put in jsbin to get all the can stuff?
Kevin Phillips
@phillipskevin
Feb 18 2018 21:51
There's a link at the top
That you can start with
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:52
i should say if you look at the example at the top
ViewModel === DefineMap
in the component it self
also a new feature of can4
and did you try one time a reduced defineMap
Kevin Phillips
@phillipskevin
Feb 18 2018 21:55
Isn't this basically what you're doing? https://donejs.com/Guide.html#messages-page
Frank Lemanschik
@frank-dspeed
Feb 18 2018 21:58
uh the guides got better
i like the new api used
:D
lgtm
Dovid Bleier
@dbleier
Feb 18 2018 22:05
here is my jsbin
it doesn't seem to be hitting the fixture though
ironically it is hitting the unitsPromise.isPending
:(
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:08
/admin_console/getUnits/1
?
why is there a 1?
this is a list
it should probally get returned by /getUnits
or does getUnit always returns lists?
Dovid Bleier
@dbleier
Feb 18 2018 22:12
I know, it's an issue with the listener on the server-side
the 1 is ignored
and I pass the real id (mongo id) via a param
anyway I was a bit incorrect
I moved my unitsPromise.isPending to the very top of my stache
and now it does show Loading Units...
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:13
so it was inside a other condition?
Dovid Bleier
@dbleier
Feb 18 2018 22:13
but it is still calling the method before it resolves
not inside, but below
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:14
then that means
you got something other that is also failing
Dovid Bleier
@dbleier
Feb 18 2018 22:14
but now I need to figure out who is calling this method since it should be inside the else
yeah, I work on this for a bit
thanks for your help
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:14
do you know can-debug?
Dovid Bleier
@dbleier
Feb 18 2018 22:15
I read about it briefly, but haven't used it
yet
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:15
if not i can suggest you to watch the current contributors meeting on youtube
Dovid Bleier
@dbleier
Feb 18 2018 22:15
ok
thanks
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:16
there at the beginning i think kevin and just do explain and show it a bit in action
Kevin Phillips
@phillipskevin
Feb 18 2018 22:16
I would suggest removing stuff feom
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:16
yes thats also good idea kevin wanted to explain its a good idea to remove propertys from your current viewmodel
make a copy of current file
and start with a empty map
and add property by property
till it fails
maybe you also want to look into donejs
that has live reload
it makes that easyer
and start with a empty map
and add property by property
Dovid Bleier
@dbleier
Feb 18 2018 22:18
I am using live-reload
Kevin Phillips
@phillipskevin
Feb 18 2018 22:18
I was going to say removing stuff from the template
Both are good ideas though
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:18
comment out in the template <!-- -->
and do the empty map thing
Dovid Bleier
@dbleier
Feb 18 2018 22:19
it seems to be calling the filter method from the stache line {{#each filter(available, filterText)}} from the can-observation onBound method
even though that line isn't being rendered yet
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:19
i would suggest doing both right
Dovid Bleier
@dbleier
Feb 18 2018 22:20
reduced to this in template
{{#if unitsPromise.isPending}}
Loading Units... 
{{else}}
<div id="unitlist">
    {{#each filter(available, filterText)}}
    <div id="unitContainer">
        </div>
        <div class="unitDelete" on:click="../delete(scope.index)">&#x2716;</div>
    </div>
    {{/each}}
</div>
{{/if}}
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:21
ah!!!
one extra suggestion
Dovid Bleier
@dbleier
Feb 18 2018 22:21
?
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:21
maybe you want to put into the else!
a if unitesPromise.isRejected
Dovid Bleier
@dbleier
Feb 18 2018 22:21
put what into the else?
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:22
there are 3 states
Rejected Resolved Pending
Dovid Bleier
@dbleier
Feb 18 2018 22:22
but it is calling filter and then is calling resolve
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:22
maybe you already got a Rejected Promise
Kevin Phillips
@phillipskevin
Feb 18 2018 22:22
You could pu a {{debugger}} above that line
Dovid Bleier
@dbleier
Feb 18 2018 22:23
no, it hasn't resolved yet
{{debugger}} didn't break
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:24
@phillipskevin can-debug can only show what tiggers what do you think we could make it also show if a condition gets executed?
Dovid Bleier
@dbleier
Feb 18 2018 22:24
but when putting breakpoint in the viewmodel
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:24
and the results=?
Kevin Phillips
@phillipskevin
Feb 18 2018 22:24
Sorry. maybe {{debugger()}}
Dovid Bleier
@dbleier
Feb 18 2018 22:28
it's the can-observation onBound method
it is calling the filter method in the #each line of the tempalte
Kevin Phillips
@phillipskevin
Feb 18 2018 22:29
Right... But you can use get to check properties in the scope
to check the status of the promise
but you might just want to wrap that section in a {{#if(available.length)}}
instead of using the promise status
I gotta run, hope you figure it out
if not, feel free to post on the forums or open an issue
so more people will see it
Dovid Bleier
@dbleier
Feb 18 2018 22:34
got it working, similar to what you said but put the check in the filter method itself to return if available hasn't resolved
thanks for you help
I really appreciate it, both of you
Frank Lemanschik
@frank-dspeed
Feb 18 2018 22:35
ah your welcome