These are chat archives for canjs/canjs

20th
Jun 2017
Justin Meyer
@justinbmeyer
Jun 20 2017 02:39
@pmgmendes can you implement getListData?
I'm not totally sure what you want to do
@/all do people like / use the recipes I've been making?
they don't get a huge amount of traffic compared to the API pages
I'm wondering if I shouldn't put effort into them that I've been putting
Gira Minus
@gKreator
Jun 20 2017 02:58
The recipes are more for beginners, kind of makes sense why most traffic goes to the api.
Personally i would focus on making like real world case boilerplates at this point.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 07:21
@justinbmeyer your recieps are well when they work :D
i thinkyou should put all your effort into getting basic stuff working for anyone
Viktor Busko
@Lighttree
Jun 20 2017 07:41

Guys, is there a way to replicate this behavior:

https://v2.canjs.com/docs/can.view.bindings.event.html

using can-event in 2.2. ?

https://v2.canjs.com/2.2/docs/can.view.bindings.can-EVENT.html

just tried: (myCustomEventOnChildViewModel)="myFunction" - this works fine in 2.3
but something like can-myCustomEventOnChildViewModel="myFunction" - doesn't work.

Frank Lemanschik
@frank-dspeed
Jun 20 2017 08:08
i think the can connect and diffrent viewmodel concepts need much more documentation
Frank Lemanschik
@frank-dspeed
Jun 20 2017 08:40
always the same questions here :) how to request data, how to store and modify data in the view model how to get realtime working
Nico R.
@nriesco
Jun 20 2017 13:29
@justinbmeyer I think the opposite as @gKreator I believe the recipes are very complex to start using canjs. I think each recipie can be subdivided in simple ones, doing one thing at a time. I have been learning can/done during the last 9-12 months and still don’t get some basics. I need some people from my team to learn can/done and I think it would be easier if they have very simple examples.
@justinbmeyer another comment is I don’t really understand how to apply all of the examples written in canjs to a donejs project. I guess for you guys is something trivial but maybe a short recipie for that could be cool. I still see canjs samples as something that needs to be adapted for donejs, and I guess it should be easier.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:06
@nriesco nope your right thats not trivial
you need to understand a lot to convert that
one key point is the usage of can.* for the recieps
in donejs you would use single packages
next key point is when converting that all the html goes into the stache as also you don't need to render parts you can use done-autorender and components
thats really a lot i converted many of the canjs recieps to donejs its a nightmare
and the concepts of the viewmodels and all the behaviers and all that is not well documented
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:12
it has all nice concepts the ideas are great but i see no time savings and its not really use able
for example last time i tryed to code a donejs application that shows pictures of 20 people and a status under the picture that live updates
i don't got it done :)
needed to finish it via jquery and socket.io directly
Justin Meyer
@justinbmeyer
Jun 20 2017 14:20
@gKreator what do you mean "real world case boilerplates"?
@frank-dspeed they haven't worked for you? What do you mean by "getting basic stuff working"?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:22
@justinbmeyer they are often not really working or reproduce able
Justin Meyer
@justinbmeyer
Jun 20 2017 14:22
@nriesco you think the Simple File Navigator and Weather Report are too complex?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:22
most times there also exist many versions of the jsbin's
Justin Meyer
@justinbmeyer
Jun 20 2017 14:23
@frank-dspeed I've not been told they aren't working
please create issues if you find one not working
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:24
sure i always try my best to raise issues but i most time never know where to start
its not easy to find the places where the issues come from
Justin Meyer
@justinbmeyer
Jun 20 2017 14:24
you can always report in canjs/canjs if it's a canjs issue
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:24
for example my last donejs feathers app don't works when it gets minifyed or packaged because of any feathers dependency
and a bug in steal
it can take weeks to track that down
my solution for this is to drop feathers and use custom api and drop steal to make sure all works
Justin Meyer
@justinbmeyer
Jun 20 2017 14:26
learning how to bisect code can help reduce the time it takes you to track errors down
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:26
in real world a app needs to work and needs to get coded in time and that was never possible :)
what is bisect?
Justin Meyer
@justinbmeyer
Jun 20 2017 14:26
start removing code
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:27
ah yes no problem lol
Justin Meyer
@justinbmeyer
Jun 20 2017 14:27
lets say there was some bug in the interplay between feathers and stealjs
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:27
i get this errors with the most simple example apps
not much code added
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 14:27
?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:27
thats why i know its the feathers model
its nothing included in the example app that is not build able :)
its simply donejs add app
Justin Meyer
@justinbmeyer
Jun 20 2017 14:28
I don't know what you mean
double negative -> "its nothing included in the example app that is not build able"
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:28
right
and then i added only one Feathers connection
and after that its not building right
Justin Meyer
@justinbmeyer
Jun 20 2017 14:29
ok, then I would remove everything else from the app ... have an index.js that just imports feathers and try to build it
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:30
its a dependency from this import Connection from 'canjs-feathers';
if minify is on it results in a C.js that gets requested thats not there
in donejs develop all works
and after build without minify the code in feathers socket commons fails
So you see this are blocking issues :D
i am using only the standart canjs-feathers
Justin Meyer
@justinbmeyer
Jun 20 2017 14:32
yeah, I think you could help yourself by being more clear when submitting issues
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:32
with 1 basic model
Justin Meyer
@justinbmeyer
Jun 20 2017 14:32
Cursor_and___feathers-socket-commons_2_4_0_lib_client___·_Issue__44_·_feathersjs_feathers-socket-commons.png
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:33
yes thats not a clear issue its pre
as i told
it will take weeks to identify it
Justin Meyer
@justinbmeyer
Jun 20 2017 14:33
pre?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:33
only a note so i know the fail is there
then i started to recode and droping feathers
to make tha application work
that got higher priority
Justin Meyer
@justinbmeyer
Jun 20 2017 14:33
yeah, but it takes 20 min for someone to figure that out
matthew / me / etc
but if the issue was written like:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:34
then make a tutorial how you figure that out
:D
i tryed it all from pritty print in console and breake on every exempt
i was so happy that i could identify that canjs-feathers is the problem
Justin Meyer
@justinbmeyer
Jun 20 2017 14:36
Title:
Unable to build feathers-socket-commons with stealjs
Description:
If a stealjs application requires `feather-socket-commons@2.4.0` like:

require("feathers-socket-commons");

it will be unable to build, providing this error:

TypeError: Cannot read property 'apply' of undefined

This seems to be due to problems in _lib/client_
Ideally, you'd also provide a repo with this minimal example breaking
this is what I mean by being able to bisect code
A million lines of code can be bisected in 20 steps
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:38
Sounds like a good method :D
Justin Meyer
@justinbmeyer
Jun 20 2017 14:38
I'm generally able to find where problems are in any codebase (not just donejs/steal/canjs) because I start removing everything
until I get something to work
and quickly narrow it down
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:38
i also use that method
but when i reach a dependency with a lot of sub dependencys
Justin Meyer
@justinbmeyer
Jun 20 2017 14:38
a build problem, especially one where stuff also works in dev, is one of the easiest to identify problems
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:39
its not any more bisect able so easy for me
Justin Meyer
@justinbmeyer
Jun 20 2017 14:39
then go into node_modules and start commenting stuff out
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:39
example the canjs-feathers code is simply not from me
i have normaly the trust
that all this will always work
Justin Meyer
@justinbmeyer
Jun 20 2017 14:39
yeah, but once you are at the point of showing that simply require("canjs-feathers") breaks ...
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:40
when i code applications my self i never had such issues
Justin Meyer
@justinbmeyer
Jun 20 2017 14:40
with a plain stealjs app
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:40
i only get this from this magic concepts that you apply here
and yes your right i will in my free time probally poste to the issue also a example repo with example server
but all that takes time :)
more time then recoding a whole application
Justin Meyer
@justinbmeyer
Jun 20 2017 14:41
it shouldn't
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:41
but in reality it does
thats the key point that i also never understood last year
Justin Meyer
@justinbmeyer
Jun 20 2017 14:42
then you might need to learn some new techniques
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:42
where makes canjs things simplyer
then doing ajax request listen via socket io for updates
and request on update again
then apply changes via jquery
Justin Meyer
@justinbmeyer
Jun 20 2017 14:42
I'm able to bisect code bases I'm unfamiliar with very quickly
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:42
goes faster then algebras
can connect
all this
Justin Meyer
@justinbmeyer
Jun 20 2017 14:42
and to create the breaking app you're talking about would look like this:
npm init
npm install steal steal-tools feathers-socket-commons --save
echo "require('feathers-socket-commons') > index.js
steal-tools
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:44
when it really breaks then
but maybe it only brakes in the real app
i would supply in my current case the feathers application server + example data
  • the models + donejs component
Justin Meyer
@justinbmeyer
Jun 20 2017 14:48
@nriesco I'm working on a more simple credit card example: http://jsbin.com/kukare/edit?html,js,output Hopefully this is closer to what you are looking for.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:48
@justinbmeyer it would be cool if you would use streams more
i love kefir streams in nodejs already
i never got can-stream or can-stream-kefir working
or other implamentations
Justin Meyer
@justinbmeyer
Jun 20 2017 14:49
I think we probably need to have both types of recipes. Very simple ones for beginners and more complex ones for advanced folks.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:49
nice would be a clock example :)
i think it would be enought if we get one complet reciep
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:49
that shows diffrent stuff
like updates in user profiles with nested data
i never got for example something working where i got languages: [ {},{}]
or even a example of some data from a api that updates :) if the data gets updated
example i have a user profile i update name in a other instance (admin interface) and it gets updated in the clients
Justin Meyer
@justinbmeyer
Jun 20 2017 14:51
pmo has live updates
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:52
ya pmo is one of the most usefull examples
with bitballs
i think my main problem is
i don't know where all this functionality comes from
and i can't read the functions
so i don't understand that
Justin Meyer
@justinbmeyer
Jun 20 2017 14:53
what do you mean
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:53
i am feeling like using magic pollyfils all over
Justin Meyer
@justinbmeyer
Jun 20 2017 14:54
which functionality?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:54
can-connect
:D
the layer that pulls data into the view model
if you are using super-map, every module that it uses is listed
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:55
i use definemap
and defineList
i don't know anything else
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 14:55
but you were talking about can-connect
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:55
yes isn't that needed?
you see i am totally lost
i am happy when i can request data in a getter
Justin Meyer
@justinbmeyer
Jun 20 2017 14:56
I think you're being a bit willfully obtuse ... though I'm happy to explain how it all fits together
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:57
thats really nice maybe that helps
Justin Meyer
@justinbmeyer
Jun 20 2017 14:58
DefineMap + DefineList are used to create observable types.
can-connect is used to connect some observable types to a service layer.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:58
so let me ask a really simpl question if you got a server that supplys json data
what would you do to display that?
Justin Meyer
@justinbmeyer
Jun 20 2017 14:58
so, I
so, I'd first model the data from the server. Say it was a bunch of Recipe data from the server.
I'd model those recipes with a Recipe DefineMap and DefineList.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 14:59
ok thats what i did so far
Gira Minus
@gKreator
Jun 20 2017 14:59

@justinbmeyer Sorry, I was getting ready for work at that moment. I was kind of thinking that there should be a boilerplate for like a simple SPA. Since that is what most people would be making with CanJs. I believe that the BitBalls app helped me figure out DoneJs and CanJs more than any of the guides or recipes. The big issue with BitBalls is that the codebase is a bit hard to fallow for a beginner, especially the models. Also, some of the VM stuff was a bit confusing at first. Other than that it seemed to have everything that was needed. I wish I understood the MVVM pattern a bit more when I started, I approached everything as MVC.

Also, I would suggest you create a github for each of the recipes so that it would be easier to see the whole code and be able to download and play with it. I would say that the advanced recipes are a bit too long. I would say to almost focus on making a bunch of smaller recipes instead, and having the tutorial in the README.MD. Some of the JsBins seem to be broken as well http://prntscr.com/fm0zau

But, like I said earlier most people are going to go to the API if they know the basics of CanJs, because if you know how the ViewModel and Component works, creating a simple file manager is very easy.

I would make a poll on the forum if you have not and ask what kind of Apps or Widgets most CanJs developers make and try to make simple recipes for those. It's very hard to want to read the ATM guide if I will never work on an ATM. Granted it is good and its the old stateless-ui example.

I hope some of this helps lol

Justin Meyer
@justinbmeyer
Jun 20 2017 15:00
Recipe = DefineMap.extend({
  id: "string",
  isTasty: "boolean",
  name: "string"
})
Recipe.List = DefineList.extend({
  "#": Recipe
})
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:00
ok that part i did and understood
now how you pull the data
Justin Meyer
@justinbmeyer
Jun 20 2017 15:00
Ok, the next step is I want to "POWER UP" the Recipe type with the ability to get data from the server.
What I want is the ability to do: Recipe.getList({}) //-> Promise<List<Recipe>>
basically, get a list of recipes
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:01
so
!
i need to define a .getList() method?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:02
this is where can-connect comes it
it adds the getList method
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:02
ah the magic :)
Justin Meyer
@justinbmeyer
Jun 20 2017 15:02
I guess if you call it magic ... I call it a mixin.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:03
yes i call all this added prototypes that i am only aware of after console log object keys magic
:D
the most interristing part is now
where does getList get called
Justin Meyer
@justinbmeyer
Jun 20 2017 15:03
When you created Recipe ... instances of recipe have .on and .each and .serialize() methods that you did not implement.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:03
and i also have things like .save
Justin Meyer
@justinbmeyer
Jun 20 2017 15:03
yes, that is what can-connect will add
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:04
ok but the most importent question is how would you call getList()
Justin Meyer
@justinbmeyer
Jun 20 2017 15:04
like:
Recipe.connection = baseMap({
  Map: Recipe,
  List: Recipe.List,
  url: "/recipes"
})
now for where to call getList
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:05
ah this map
is the set of behaviers?
so i can choose baseMap superMap
?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:05
baseMap adds a bunch of different behaviors
constructor, constructor/store, data/url, etc
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:05
ok so far so good so that the configuration point
Justin Meyer
@justinbmeyer
Jun 20 2017 15:06
all of them have the effect of adding Recipe.getList
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:06
ok thats why the map needs to know the algebra
Justin Meyer
@justinbmeyer
Jun 20 2017 15:06
and things like recipe.save(), recipe.isSaving(), etc
ah ... so that's one final thing ..
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:06
to configure the behaviers
Justin Meyer
@justinbmeyer
Jun 20 2017 15:06
say your service layer /recipes
supports different params like:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:07
limit query and so skip (pagination)
Justin Meyer
@justinbmeyer
Jun 20 2017 15:07
/recipes?start=20&end=40&sort=isTasty
you can teach the connection about these params with set.Algebra like:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:07
yes i understand so far thats exactly the point :) where magic happens
i think one key lesson now was the the map sets how data gets pulled and the map i guess uses can-connect right?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:09
DefineMap defines the behavior of the data once it's in the browser.
can-connect defines how the raw data gets pulled into the browser.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:09
good stuff so far
Justin Meyer
@justinbmeyer
Jun 20 2017 15:10
set.Algebra teaches can-connect about the nature of those params, things like start=20&end=40&sort=isTasty
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:10
import set from 'can-set';
import helpers from 'can-set/src/helpers';

/**
 * Feathers-compatible can-set algebra for can-connect Models.
 */
export default new set.Algebra(
  set.comparators.id('_id'),
  set.props.offsetLimit('$skip', '$limit'),
  set.comparators.sort('$sort', defaultSort),
  {
    '$populate': function () {
      return true;
    }
  }
);

// TODO: this should belong to can-set module: `can-set/src/helpers.defaultSort`
// See this PR: https://github.com/canjs/can-set/pull/25/commits/b744d23cba7bccd694a858853560c7d816b26f42
// Gives back the value of an object at a provided dot-separated path string.
helpers.getValueFromPath = function getValueFromPath (obj, path) {
  path = path.split('.');
  for (var i = 0; i < path.length; i++) {
    obj = obj[path[i]];
  }
  return obj;
};

function defaultSort (sortPropValue, item1, item2) {
  var parts = [];
  var sortProp;
  var item1Value;
  var item2Value;
  var desc;

  if (typeof sortPropValue === 'string') {
    parts = sortPropValue.split(' ');
    sortProp = parts[0];
    item1Value = item1[sortProp];
    item2Value = item2[sortProp];
    desc = parts[1] || '';
    desc = desc.toLowerCase() === 'desc';
  } else {
    var path = Object.keys(sortPropValue)[0];
    var sortDir = sortPropValue[Object.keys(sortPropValue)[0]];
    if (sortDir === -1 || sortDir === '-1') {
      desc = true;
    }

    item1Value = helpers.getValueFromPath(item1, path);
    item2Value = helpers.getValueFromPath(item2, path);
  }

  if (desc) {
    var temp;
    temp = item1Value;
    item1Value = item2Value;
    item2Value = temp;
  }

  if (item1Value < item2Value) {
    return -1;
  }
  if (item1Value > item2Value) {
    return 1;
  }
  return 0;
}
look this for example is from a offical example and produces a api request like /recieps::find
thats clear wrong
with this algebra i get a wrong request on .findAll()
Justin Meyer
@justinbmeyer
Jun 20 2017 15:12
yeah, we are working on making set.Algebra a bit easier to work with cc @nlundquist
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:12
in general this can't be so complicated
Justin Meyer
@justinbmeyer
Jun 20 2017 15:12
yeah, don't use real-time
and then you really don't need to configure your algebra
instead of baseMap
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:13
but i need realtime
i code realtime applications
but i mastered bypassing realtime parts
via simply putting them in custom socket.on instructions in the defineMap init
:D
what i don't mastered is knowing when stache is rendered so that i can select parts with jquery
i bypass that via setTimeout
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 15:14
select parts?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:15
often i have for example a div in my stache that needs updates
Justin Meyer
@justinbmeyer
Jun 20 2017 15:15
this has gotten a bit off subject
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:15
as i can't do it via defineMap i need to do it in a socket.on('update') function
Justin Meyer
@justinbmeyer
Jun 20 2017 15:15
but you shouldn't use jQuery to touch the DOM almost ever
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:15
there is no alternate
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 15:15
I'm betting there is
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:15
i need something that simply takes aktion on update
Justin Meyer
@justinbmeyer
Jun 20 2017 15:15
you should update the data
and let live-binding update the page
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:16
you mean i can live bind a defineMap property
and then set it from outside of the viewModel?
i never got that working
this stuff only worked from functions inside the defineMap
Justin Meyer
@justinbmeyer
Jun 20 2017 15:17
yeah, I'm not 100% sure what you are talking about ... but yes ... if you wanted say to do real-time w/o can-connect/real-time ... you have to keep your own store of instances
and then update them
which is basically what real-time does
real-time is just smart enough to also update lists of things
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:18
instances :) there it gets complex
Justin Meyer
@justinbmeyer
Jun 20 2017 15:18
complex?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:18
i am really talking about the most simple data structures and actions
like socket.io simply fires update: id
then a function does a request for that data
thats it
Justin Meyer
@justinbmeyer
Jun 20 2017 15:18
it doesn't push the new data?
socket.io doesn't push the new data
?
I mean, it really doesn't matter
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:19
not at present
i also could let it push data
but i am a fan of kiss keep it simple
most importent is that it works
and that its fast
Justin Meyer
@justinbmeyer
Jun 20 2017 15:19
ok, so with can-connect/real-time this is all very simple if you have your set.Algebra configured
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:20
yes probally it is thats what i am beliving in since more then a year
Justin Meyer
@justinbmeyer
Jun 20 2017 15:20
but you could build your own real-time pretty simply too ...
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:20
i am a simple javascript coder focused on getting stuff running
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 15:20
especially if you were using can-connect/constructor-store
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:21
i don't know what can-connect constructor store and all that is
Justin Meyer
@justinbmeyer
Jun 20 2017 15:21
but lets make something stupidly simple (and leaking memory) ourselves
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:21
and thats probally the problem
Justin Meyer
@justinbmeyer
Jun 20 2017 15:21
after the can-connect above:
actually, replace that with:
var recipesById = {};
Recipe.getList = function(){
  return ajax({url: "/recipes"}).then(function(recipes){
    var list = new Recipe.List(recipes);
    recipes.forEach(function(recipe){
      recipesById[recipe.id] = recipe
    })
    return list;
  })
};
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:24
ya that code looks logical for me
Justin Meyer
@justinbmeyer
Jun 20 2017 15:24
then have:
UPDATE_RECIPE = function(id, recipeData){
  recipesById[id].set(recipeData);
}
can-connect/constructor/store is basically providing recipesById
and can-connect/real-time provides UPDATE_RECIPE
            var instance = this.instanceStore.get( this.id(params) );
            this.updatedInstance(instance, props);
            update.call(this, this.serializeInstance(instance));
real-time is saying
  1. get me the instance ...
  2. update the instance
  3. update the instance in any lists
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:26
with instance we reference what exactly
Justin Meyer
@justinbmeyer
Jun 20 2017 15:26
?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:26
a Instance of the defineMap ?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:26
yes
an instance of new Recipe()
basically, constructor-store keeps a map of every instance's id to the instance
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:27
ok and that should be a single right?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:27
there should only be a single instance for a given ID
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:27
yes thats what i meand
and then the constuctor offers also getList
for getting a list of instances by id
Justin Meyer
@justinbmeyer
Jun 20 2017 15:28
generally not by id
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:28
by algebra
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 15:28
but by some filter/search/sort/paginate criteria
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:28
and that criteria is set in algebra right?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:28
which is modeled with set.Algebra
yes
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:28
or in the Map?
ok
Justin Meyer
@justinbmeyer
Jun 20 2017 15:29
constructor-store also keeps a map of lists too
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:29
Lists?
shouldn't be only one list be there?
of the recieps
Justin Meyer
@justinbmeyer
Jun 20 2017 15:29
not only is there the instanceStore which looks like {5: new Recipe({id: 5}), 6: new Recipe({id: 6}}
there's a listStore that looks like:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:30
and why exactly do we need to store so much info?
where does this stores get read?
Justin Meyer
@justinbmeyer
Jun 20 2017 15:31
{
  "{start:0,end:10}": [ new Recipe({id: 5}), .... ],
  "{start:10,end:20}: [ new Recipe({id: 6}), .... ],
}

where does this stores get read?

We answered this already.

            var instance = this.instanceStore.get( this.id(params) );
            this.updatedInstance(instance, props);
            update.call(this, this.serializeInstance(instance));
real-time tracks the instances and lists to be able to update their data
to be clear ... we aren't really storing anything that the page isn't already storing
we just have it organized
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:33
yes ok you mean you only reference the original data
Justin Meyer
@justinbmeyer
Jun 20 2017 15:33
just like the little example I wrote above
var recipesById = {};
Recipe.getList = function(){
  return ajax({url: "/recipes"}).then(function(recipes){
    var list = new Recipe.List(recipes);
    recipes.forEach(function(recipe){
      recipesById[recipe.id] = recipe
    })
    return list;
  })
};
recipesById only has references to the instances already created by .getList
the problem with what we did in this small example is that it will leak memory. can-connect/constructor/store doesn't have this problem
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:34
ok so where does get list get called :)
because as far as i understand as soon as this got called i should have my data ready to be rendered
Justin Meyer
@justinbmeyer
Jun 20 2017 15:35
.getList is async
so is called, but a promise is returned
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:36
yes thats totall ok :) i can even set the promise like a reciepePromise
and then listen in a template stache for isResolved
Justin Meyer
@justinbmeyer
Jun 20 2017 15:36
yes
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:36
but the problem still is when where call getList
Justin Meyer
@justinbmeyer
Jun 20 2017 15:36
so where to call getList depends on how complex the app is
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:36
not complex
1 model
2 values
:D
Justin Meyer
@justinbmeyer
Jun 20 2017 15:36
if the app was just this .. just listing recipes and NO other functionality
I might just do something like:
var view = stache("{{#if recipesPromise.isResolved}} .... ");
var frag = view({
  recipesPromise: Recipes.getList({})
})
document.body.appendChild(frag)
if it's a tiny bit more complex, I'd create a ViewModel for the page like:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:38
let me think about that the donejs way
Justin Meyer
@justinbmeyer
Jun 20 2017 15:39
ok, well if this was a donejs app, I'd just make recipesPromise part of the AppViewModel:
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:39
ok i understand
i should set a recipesPromise: Recipes.getList({})
and wait till it is resolved and the render each value
Justin Meyer
@justinbmeyer
Jun 20 2017 15:40
AppViewModel = DefineMap.extend({
  recipesPromise: {
    value: function(){
      return Recipes.getList()
    }
  }
})
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:40
but i understand right that this list only updates realtime
if a item gets added or removed
not if a value changes right
Justin Meyer
@justinbmeyer
Jun 20 2017 15:40
no, if a value changes
again, these three lines:
            var instance = this.instanceStore.get( this.id(params) );
            this.updatedInstance(instance, props);
            update.call(this, this.serializeInstance(instance));
  1. gets the item from the store
  2. updates its data (which is what you want)
  3. adds or removes it from lists
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:42
hmmm i think i need to wrapp my mind around this
because i don't know where i read this instance store
when i read the object instance store
it would need to hold the updated data already
or does the instanceStore produce real requests?
how can i manual update something what does can-connect for example expect
as data structure
on update or something
when i update for example a reciepe on the server what should i fire via socket.io so
that it knows the new data
my first idea would be fire update and then recall reciepsPromise
the last part i am missing is the connection from server to can connect maybe
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:49
recieps.updateInstance({})
needs to get fired with instance data right?
i understood a lot of more today but i feel still so far away from understanding how this works with canjs :) with jquery i listen to my events then parasing my data and apply changes to dom works really simply
Justin Meyer
@justinbmeyer
Jun 20 2017 15:57
@frank-dspeed it won't scale
say you are TodoMVC and list the number of completed todos and active todo count
you'd have to know to change the DOM in 3 spots
if a todo changed from complete: true to complete: false
Frank Lemanschik
@frank-dspeed
Jun 20 2017 15:59
thats not a problem
i simply code 1 function that updates 3 places
it takes 1 param the changed stuff
i can assign a class to all elements with name like id22
then i look is .id22 there? no add if there update
Justin Meyer
@justinbmeyer
Jun 20 2017 16:02
yeah, that doesn't scale well
it makes that piece of code aware of all other parts of the code
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:03
maybe but it works so its highly favored
Justin Meyer
@justinbmeyer
Jun 20 2017 16:03
nothing can happen in isolation
not favored by any framework
they are all designed to avoid this type of thing
to keep data / state as the source of truth
instead of the DOM
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:04
i like the concept
but its to big for me probally :)
i only code some office tools and some high traffic sites
for example the real time stuff should simply display who is in office and who not
:D
with donejs i was investigating 3 weeks now my jquery solution was up and working after 4 hours
Pedro Mendes
@pmgmendes
Jun 20 2017 16:38
This message was deleted
Pedro Mendes
@pmgmendes
Jun 20 2017 16:46

@justinbmeyer Consider a situation where you want to get a reference to the promise returned by Type.getList() in order to resolve it later.

var Item = DefineMap.extend({
   id: "string",
   children: {
      type: "any",
      get() {
        return SubItem.getList({parent: this.id});
      }
   }
});

# component viewmodel
var CatalogVM = DefineMap.extend({
  active: "boolean",
  entry: Item,
  entryItems: {
    get(lastSetVal, resolve) {
      let children = this.entry.children;
      if (this.ative) {
        children.then(data => {
          resolve(data);
        }, error => {
          resolve([]);
        });
      }
      return [];
    }
  }
});

# componet template
{{#each entryItems}}
  ...
{{/each}}

The issue is that as soon as the children getter is called at let children = this.entry.children the SubItem.getList() executes forcing the getListdata promise to be resolved internally by the constructor behavior. And I just want the subitem list to be fetch when the parent item is active.

Justin Meyer
@justinbmeyer
Jun 20 2017 16:48

@gKreator Thanks for the feedback. That JSBin is working. It's the starting JSBin. It shows the styles with mocked-up HTML.

Can you help me understand why you want shorter recipes, but you find Bitballs the most useful? That seems a bit contradictory.

@pmgmendes reading your post ...
Mohamed Cherif Bouchelaghem
@cherifGsoul
Jun 20 2017 16:50
@justinbmeyer I think are fine I consult theme often, I think we should mention the purpose of each receipe and what is the highlights of each one
Justin Meyer
@justinbmeyer
Jun 20 2017 16:52
good suggested @cherifGsoul ! If you wanted to add that, they can all be found here: https://github.com/canjs/canjs/tree/master/docs/can-guides/commitment/recipes :-)
Mohamed Cherif Bouchelaghem
@cherifGsoul
Jun 20 2017 16:52
@justinbmeyer of course
Justin Meyer
@justinbmeyer
Jun 20 2017 16:52
u r #1!
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:52
@cherifGsoul and maybe make canjs and donejs examples the same :)
so that some one can understand how to do it the donejs way
a little set of example configuration for running nodejs and other web applications at scale in production
Mohamed Cherif Bouchelaghem
@cherifGsoul
Jun 20 2017 16:54
@frank-dspeed canjs is a toolkit which let's you easily model your architecture to solve applications problems
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:54
yes yes really easy :)
Mohamed Cherif Bouchelaghem
@cherifGsoul
Jun 20 2017 16:54
there's no one line to connect every dot
Justin Meyer
@justinbmeyer
Jun 20 2017 16:54

@pmgmendes what do you mean by:

And I just want the subitem list to be fetch when the parent item is active.

oh, when .active is true?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:55
active means selected
yes
Pedro Mendes
@pmgmendes
Jun 20 2017 16:55
@justinbmeyer @frank-dspeed Exactly!
Justin Meyer
@justinbmeyer
Jun 20 2017 16:55
Do you mean when .active changes to true ... a new fetch every time?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:55
i guess this will get really easy :)
Justin Meyer
@justinbmeyer
Jun 20 2017 16:56
could you just read .children inside the if(this.active) check?
   get(lastSetVal, resolve) {

      if (this.active) {
        let children = this.entry.children;
        children.then(data => {
          resolve(data);
        }, error => {
          resolve([]);
        });
      }
      return [];
    }
  }
Gira Minus
@gKreator
Jun 20 2017 16:57
@justinbmeyer I like the shorter recipes since they are easier to see the framework in action, plus it would be easier to churn them out for you. The reason I liked BitBalls the most is because that was the closest to what I was making at the time. It had everything like models, routing, and auto-render.
Frank Lemanschik
@frank-dspeed
Jun 20 2017 16:58
yes bitballs is not as big :) it only has some basic stuff
user, player, tournament, session,
really not much but even that gets complicated :D
Pedro Mendes
@pmgmendes
Jun 20 2017 16:59

@justinbmeyer

Do you mean when .active changes to true ... a new fetch every time?

Not exactly. I've over simplified the sample code.

could you just read .children inside the if(this.active) check?

Give me a sec to try that.

Justin Meyer
@justinbmeyer
Jun 20 2017 17:01
@gKreator hopefully this Credit Card one will be about right
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:03
@justinbmeyer one question when you would get data via socket.io only how would you set values on a define map?
with can-connect and set algebra?
Justin Meyer
@justinbmeyer
Jun 20 2017 17:05
what do you mean by "via socket.io only"
if I'm using can-connect and such, w/ real-time you do it like
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:05
that means you have a socket-client running that throws for example: 'coin', 2
so on coin and the number of coins
Justin Meyer
@justinbmeyer
Jun 20 2017 17:05
socket.on('orders created', order => Order.connection.createInstance(order));
socket.on('orders updated', order => Order.connection.updateInstance(order));
socket.on('orders removed', order => Order.connection.destroyInstance(order));
the connection has createInstance, updateInstance and destroyInstance methods
those will find the instance in the store, and update it appropriately
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:06
ok that sounds logical
i think i understand that :)
but does Order need a connection?
or does it get that in any case?
i think Order would be my defineMap
Justin Meyer
@justinbmeyer
Jun 20 2017 17:08
I'm confused a bit by that
it makes me think I'm not communicating something important
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:08
maybe because you think a other way then me
Justin Meyer
@justinbmeyer
Jun 20 2017 17:08
can-connect is what is provides connections ...
Pedro Mendes
@pmgmendes
Jun 20 2017 17:08

@justinbmeyer

could you just read .children inside the if(this.active) check?

In this case I can't...
I forgot to mention but the CatalogVM.entryItem could be an Item or any given DefineMap with children prop that might be a Promise or a static DefineList. So the CatalogVM resembles something like

var CatalogVM = DefineMap.extend({
  active: "boolean",
  entry: DefineMap,
  entryItems: {
    get(lastSetVal, resolve) {
      let children = this.entry.children;
      if (this.ative) {
          if (isPromiseLike(children)) {
            children.then(data => {
              resolve(data);
            }, error => {
              resolve([]);
            });
        } else {
         return children;
        }
      } 
      return [];
    }
  }
});
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:08
i think out of the view that i put into my app.js simply a require for a socket client
Justin Meyer
@justinbmeyer
Jun 20 2017 17:09
ok
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:09
then i instance that and on update how do i set a value on a defineMap
@frank-dspeed again ... are you asking this with respect to how to use can-connect?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:10
no i was planning to maybe even don't use it
thats why i am asking
Justin Meyer
@justinbmeyer
Jun 20 2017 17:10
ok, then please answer that next time
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:10
but when it works with that i am also happy
i think i will try some stuff with that order model and look if that works as expected
but i think there should be a easy way
to listen for data and set it
on a defineMap
Justin Meyer
@justinbmeyer
Jun 20 2017 17:11
there isn't / shouldn't be
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:11
because of your VM concept right?
Justin Meyer
@justinbmeyer
Jun 20 2017 17:11
I think you need to understand ... CanJS (and many other things) are built in layers
none of this has to do with VM
this is entirely model layer
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:12
i understand that
i coded really big applications but i did that server side
Justin Meyer
@justinbmeyer
Jun 20 2017 17:12
then why would VM be related?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:12
i don't know i think because of the context
Justin Meyer
@justinbmeyer
Jun 20 2017 17:12
big server-side applications are very different from big client apps
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:12
i am normaly able to set any variable from any where
i am also able to require every thing from every where and get the same object
Justin Meyer
@justinbmeyer
Jun 20 2017 17:13
being able to set a variable from anywhere isn't great ... globals are terrible
a lot of engineering work goes into making things isolated
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:13
i mean even from any where in the code :)
example the socket.on() function
i am normaly able to supply it a function that sets a variable
that i can read then later some how or poll it
Justin Meyer
@justinbmeyer
Jun 20 2017 17:14
yeah, this is similar
Order.connection = superMap({
  url: loader.serviceBaseURL + '/api/orders',
  Map: Order,
  List: Order.List,
  name: 'order',
  algebra
});

const socket = io(loader.serviceBaseURL);

socket.on('orders created', order => Order.connection.createInstance(order));
socket.on('orders updated', order => Order.connection.updateInstance(order));
socket.on('orders removed', order => Order.connection.destroyInstance(order));
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:14
yes but it calles the order connection functions
Justin Meyer
@justinbmeyer
Jun 20 2017 17:14
so?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:14
i would love a way without connection
because socket.io
Justin Meyer
@justinbmeyer
Jun 20 2017 17:15
I showed you this already
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:15
is my connection already
Justin Meyer
@justinbmeyer
Jun 20 2017 17:15
I showed you how to do this already
var recipesById = {};
Recipe.getList = function(){
  return ajax({url: "/recipes"}).then(function(recipes){
    var list = new Recipe.List(recipes);
    recipes.forEach(function(recipe){
      recipesById[recipe.id] = recipe
    })
    return list;
  })
};
socket.on('recipe updated', function(recipeData){
  recipesById[recipeData.id].set(recipeData)
});
but "because socket.io" is a very strange argument against a connection
especially as the can-connect code uses socket.io
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:17
so as text you mean: create Model. define var and write getList prototype that sets a value to var and then reset data on that var
not reset
set data on var
Justin Meyer
@justinbmeyer
Jun 20 2017 17:18
@pmgmendes I still don't know why you can't read the value w/i the if()?
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:19
OH Wait i know what makes my question wrong :)
we are always talking probally about lists
what if we talk about a single value
that i only want to update on the dome
dom
only a Little Text that comes from socket.on('update')
can i set that text some how on a defineMap
so that stache gets updated
so lets say i have a AppViewModel with a single value message
Justin Meyer
@justinbmeyer
Jun 20 2017 17:21
var recipesById = {};
Recipe.get = function(){
  return ajax({url: "/recipes/the-rceipe"}).then(function(recipe){
    var recipe = new Recipe(recipe);
    recipesById[recipe.id] = recipe
    return recipe;
  })
};
Frank Lemanschik
@frank-dspeed
Jun 20 2017 17:21
now i want to do socket.on('update', message => AppViewModel.message = message)
i am wondering if i can write a set method :)
Jeroen Cornelissen
@jeroencornelissen
Jun 20 2017 19:26
@justinbmeyer I kind of agree with what has been said. The recipies are very interessting, but shorter and simpler recipies that build up to something large would be better.
I also like the widgetry video’s. They are very well explained and often give some more side info to what is said in the recipies on the site.
We have been using JavascriptMVC, CanJS 1/2/3 for a few years now and I really like how things evolve. Components are a real improvement over can.Control. The step to learning v3 was bigger and a bit harder. But now we are getting the hang of it. … But Algebra is still a mystery ;-)
Jeroen Cornelissen
@jeroencornelissen
Jun 20 2017 19:37
We’ve invested some time in DoneJS (when it was still in beta) but haven’t made the switch yet. For now I don’t see any advantage in using DoneJS… So maybe it’s what @frank-dspeed said, we’re missing some guidance in moving from Can to Done. And explaining the advantages/differences or why we should move.
But keep up the good work, we use your products every day! :clap: :clap: :clap:
Nico R.
@nriesco
Jun 20 2017 20:19
@justinbmeyer take a look at knockoutjs doucumentation. It is very basic, actually I think your recipies are way more useful and advanced but these samples teach you the basic tools, then you can go anywhere: http://knockoutjs.com/examples/ and http://learn.knockoutjs.com/
Justin Meyer
@justinbmeyer
Jun 20 2017 20:22
@jeroencornelissen DoneJS is mostly just CanJS + StealJS ... organized in a way to take full advantage of everything, plus server-side-rendering, builds to Cordova/Electron, etc