These are chat archives for canjs/canjs

13th
Dec 2016
swipie
@swipie
Dec 13 2016 10:26

I'm trying to let my app work with fixtures. The fixture looks like this:

fixture({method: "GET", url: "/Foo/getFooBar"},
    function(request, response, headers, ajaxSettings) {
        return [
            { "Foo" : "Bar" }, 
            { "Bar" : "Foo" }
        ];
    }
)

The fixture works, I get the data back but the problem is that I get the data as a string, not a JSON object.
Where I get my data from the fixture I have to do this: data = JSON.parse(data); to make it work.
So everytime I turn off my fixtures I have to comment those lines to make it work with the real back end.

Is it possible to get my data directly as a JSON object from my fixtures?

Frank Lemanschik
@frank-dspeed
Dec 13 2016 14:05
thats not realy logical
there is probally a design fail
Kevin Phillips
@phillipskevin
Dec 13 2016 14:39
@swipie you can set the content-type header to make sure JSON is sent
can.fixture({method: "GET", url: "/Foo/getFooBar"},
    function(request, response, headers, ajaxSettings) {
        response(200,
        [
            { "Foo" : "Bar" }, 
            { "Bar" : "Foo" }
        ],
        { 'content-type': 'application/json' });
    }
);
swipie
@swipie
Dec 13 2016 14:47
@phillipskevin Thanks!
Kevin Phillips
@phillipskevin
Dec 13 2016 15:08
no problem
Chasen Le Hara
@chasenlehara
Dec 13 2016 17:21
We published the CanJS 3 release article this morning 🎉 https://www.bitovi.com/blog/canjs-3-0-release
Thomas Sieverding
@Bajix
Dec 13 2016 18:05
;o
Nice
What’s happening w/ jQuery 2 vs jQuery 3? can-jquery uses 3.x and yet a number of the can repos are using 2.x
Chasen Le Hara
@chasenlehara
Dec 13 2016 18:24
We just haven’t had the time to upgrade them yet, but we will (or we’ll accept PRs 🙂).
Thomas Sieverding
@Bajix
Dec 13 2016 18:28
It’s problematic having mismatched versions no?
Justin Meyer
@justinbmeyer
Dec 13 2016 18:35
cc @phillipskevin can-jquery should be specifying 2.X-3.X as its range
allowing any of those versions to be used
Thomas Sieverding
@Bajix
Dec 13 2016 18:38
Just doing a quick shrinkwrap shows steal-stache & can-connect loading jQuery 2.x
I can take a look at upgrading those
can-connect & steal-stache should depend on can-jquery instead of jquery directly no?
I suppose it’s maybe irrelevant for those two
Thomas Sieverding
@Bajix
Dec 13 2016 18:58
@justinbmeyer canjs/steal-stache#11 & canjs/can-connect#210
Those upgrade deps including jQuery
Justin Meyer
@justinbmeyer
Dec 13 2016 19:01
Thanks, I think it needs to be changed to allow both 2.X and 3.X
Thomas Sieverding
@Bajix
Dec 13 2016 19:01
I can update the PR for that
thanks!
Thomas Sieverding
@Bajix
Dec 13 2016 19:48
@justinbmeyer canjs/steal-stache#11 & canjs/can-connect#210 are ready
Nico R.
@nriesco
Dec 13 2016 21:28

I’m confused when to use define. I had an app that was working perfectly fine but when it came to testing I just couldn’t test a function what was within a “define”. The code is something like this:

export const myModel = can.Map.extend({
  define: {
    oldWay: {
      get() {
        return 123;
      }
    }
  },
  newWay: function() {
    return 123 + 'new way';
  }
});

both work exactly the same (at least the way I use them).
The problem is when trying to do some tests. I just couldn’t test ‘oldWay’ but ‘newWay’ was fully testable. I also noticed that on one you need to test it calling myModel.newWay() whereas the oldaway was myModel.oldWay

I guess the big question is when to use define, when to use defineMap and when not to.

Thanks

Kevin Phillips
@phillipskevin
Dec 13 2016 21:30
with can.Map and the define plugin, you should use myModel.attr(‘oldWay’) to get the value of that property
it is not a function… with get you are defining a “virtual” property on the map
the more equivelant way to think about it would be
export const myModel = can.Map.extend({
  define: {
    oldWay: {
      get() {
        return 123;
      }
    }
  },
  newWay: 123
});
then myModel.attr(‘oldWay’) and myModel.attr(‘newWay’) would behave the same
Kevin Phillips
@phillipskevin
Dec 13 2016 21:36
I think “when to use DefineMap” is a difficult question to answer
different developers probably have different preferences
I default to using the define plugin or DefineMap all the time, unless I run into a reason not to
Nico R.
@nriesco
Dec 13 2016 21:59
Oh I see
And what about a "computed" property such as full name or age?
Should it be "defined"?
Kevin Phillips
@phillipskevin
Dec 13 2016 22:00
yes
Nico R.
@nriesco
Dec 13 2016 22:01
But I've seen some defined properties that have a setter
That is confusing
Kevin Phillips
@phillipskevin
Dec 13 2016 22:02
why?
that is normally done when you need some side effect of setting a value
that goes through a lot of the use cases for the define plugin of can.Map
DefineMap is intended to do all of the same things, but without the need to call .attr() to get or set properties
Nico R.
@nriesco
Dec 13 2016 22:08
If I have "amount" and define "formattedAmount" a getter could add "$" and the setter could extract only the number, parse it and store it in "amount"?
Kevin Phillips
@phillipskevin
Dec 13 2016 22:09
I think in that case you wouldn’t want to set formattedAmount
Kevin Phillips
@phillipskevin
Dec 13 2016 22:21
but yes, you could do that
Nico R.
@nriesco
Dec 13 2016 22:41
@phillipskevin what would you say is the best fit for a defined property? Besides promises that seem to fit naturally in there
and what about testing, if I have some complex logic within the defined property I think it must be defined somewhere else to test it (at least I wasn’t able to test it at all). where is that place? an external library? within the same file (in my case the model) or some sort of util library?
Kevin Phillips
@phillipskevin
Dec 13 2016 22:44
I’m not sure what you mean by your first question
about testing, definied properties should be great for testing
in your example, you just need to call myModel.attr(‘oldWay’) to get the result of your get() function
Nico R.
@nriesco
Dec 13 2016 22:50
ok
with the first question I mean what type of problems/situations are obviously solved using define/virtual properties, any good example of something what couldn’t be solved using “normal” properties?
Kevin Phillips
@phillipskevin
Dec 13 2016 22:56
I think most things could be solved, but the define plugin makes the code a lot more readable and performant
things that are really difficult to do without the define plugin are the more “aspect oriented” issues
for example, if you need to keep a list of changes made to a model
or you need to log something to the server whenever a property changes
but I don’t use those things as often as I do derived properties
Nico R.
@nriesco
Dec 13 2016 23:00
ok thanks @phillipskevin
Kevin Phillips
@phillipskevin
Dec 13 2016 23:02
this kind of thing is what I use most often
  get active(){
    return this.filter({complete: false});
  },
  get complete(){
    return this.filter({complete: true});
  },
  get allComplete(){
    return this.length === this.complete.length;
  }
those are all computed properties based on the same list
Thomas Sieverding
@Bajix
Dec 13 2016 23:02
@phillipskevin Those are on the List’s prototype?
Kevin Phillips
@phillipskevin
Dec 13 2016 23:02
not having to manually update all of those properties every time the list changes is a huge benefit
@Bajix yeah
that’s just from the todomvc guide
Thomas Sieverding
@Bajix
Dec 13 2016 23:04
I’ve always been worried about that kind of behavior resulting in unnecessary layout thrashing
I previously accomplished the behavior above with https://www.npmjs.com/package/can-derive
Kevin Phillips
@phillipskevin
Dec 13 2016 23:04
have you seen issues like that?
Thomas Sieverding
@Bajix
Dec 13 2016 23:05
Yea - a lot actually
Kevin Phillips
@phillipskevin
Dec 13 2016 23:05
ok
I’d be curious if they’re still present in 3.0
Thomas Sieverding
@Bajix
Dec 13 2016 23:06
I have an example of this actually now that I think about it
Kevin Phillips
@phillipskevin
Dec 13 2016 23:06
or if can-view-live list handles it better
I’ve got to move my car, but if you can point me to the example I’d love to take a look later on
Thomas Sieverding
@Bajix
Dec 13 2016 23:07
Well what I’d really like to be able to do is have a way to return a set that’s derivative of a lot of different properties that doesn’t result in rerendering an entirely new list every time
canjs/canjs#2878
@phillipskevin ^
That’s a pretty complicated derive use-case that’s only viable if it doesn’t trigger a rerender of the entire list
Kevin Phillips
@phillipskevin
Dec 13 2016 23:23
ok
did you ever get an answer about can-derive being updated for 3.0?
Thomas Sieverding
@Bajix
Dec 13 2016 23:23
Oh no I hadn’t
I think there are maybe alternate approaches that 3.0 offers though
Thomas Sieverding
@Bajix
Dec 13 2016 23:31
@phillipskevin How does can-view-live handle replacing lists with subsets?
Kevin Phillips
@phillipskevin
Dec 13 2016 23:34
it gets a list of patches based on the diff of the two lists
so if you’re replcing with a subset, you should just get remove events
Thomas Sieverding
@Bajix
Dec 13 2016 23:34
Sweet! I’ve been hoping that’d make it in for a while
I could rebuild my stuff to just virtualize the set params, couple it w/ can-stream to debounce, then return new Lists from the dynamic set
Man that’s literally been on my wish list for like 3 years
That’s beautiful work :D
can-view-live makes my use-case for can-derive solveable just with can-connect alone
Kevin Phillips
@phillipskevin
Dec 13 2016 23:40
awesome
part of what I said isn’t exactly true I guess, you probably won’t get only remove events
Thomas Sieverding
@Bajix
Dec 13 2016 23:43
I’d get events based off of the diff
Which is what I want ^^
Kevin Phillips
@phillipskevin
Dec 13 2016 23:43
yeah
out of curiousity I was testing it out
and you might get only remove events… but you might not
nevertheless, you get events based off the diff
Thomas Sieverding
@Bajix
Dec 13 2016 23:45
I was just thinking… with your earlier example wherein you used an object to do the filter - that would be way more efficient if you were returning a new List with a merged set
Kevin Phillips
@phillipskevin
Dec 13 2016 23:46
I’d have to try it out
Thomas Sieverding
@Bajix
Dec 13 2016 23:47
get active() { return new List(Object.assign({}, this.__listSet, { active: true })); }
Kevin Phillips
@phillipskevin
Dec 13 2016 23:51
I don’t know that I understand listSet well enough… what would that do exactly?
Nico R.
@nriesco
Dec 13 2016 23:53

@phillipskevin I saw your example and those are great examples. On knockoutjs you could define the way this kind of “computed” attributes were updated, can you do that in can?

this kind of thing is what I use most often

  get active(){
    return this.filter({complete: false});
  },
  get complete(){
    return this.filter({complete: true});
  },
  get allComplete(){
    return this.length === this.complete.length;
  }
Thomas Sieverding
@Bajix
Dec 13 2016 23:53
It’s the set Algebra used to query against
Nico R.
@nriesco
Dec 13 2016 23:55
you could for example wait 100 milliseconds before the update or stuff like that
Thomas Sieverding
@Bajix
Dec 13 2016 23:55
So you’d be returning a new list that’s a subset of the original list, and you’d just rely that they’d be managed via can-connect
can-stream does that
Nico R.
@nriesco
Dec 13 2016 23:56
I’m worried because when dealing with lists of complex objects it would get slow when dealing with small sets of say 30 or 50 causing the application to use a lot of cpu
Kevin Phillips
@phillipskevin
Dec 13 2016 23:57
you could do that manually
using an asynchronous getter
but I would wait until you run into an issue like that before doing that kind of thing
most of the time, you should let the event batching system take care of that kind of thing for you
@Bajix wouldn’t this.__listSet tell can-connect that it’s the same list?
Thomas Sieverding
@Bajix
Dec 13 2016 23:58
@phillipskevin You’d merge the two sets
Nico R.
@nriesco
Dec 13 2016 23:58
@phillipskevin ok thanks!
Kevin Phillips
@phillipskevin
Dec 13 2016 23:59
ok @Bajix I’m sure I’ll understand some day
for now I’m going to take your word for it :smile: