Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 05:21

    greenkeeper[bot] on steal-2.2.4

    chore(package): update steal to… (compare)

  • Oct 21 18:27
    greenkeeper[bot] labeled #5392
  • Oct 21 18:27
    greenkeeper[bot] opened #5392
  • Oct 21 18:27

    greenkeeper[bot] on core-js-3.3.3

    chore(package): update core-js … (compare)

  • Oct 18 22:20
    greenkeeper[bot] labeled #5391
  • Oct 18 22:20
    greenkeeper[bot] opened #5391
  • Oct 18 22:20

    greenkeeper[bot] on can-observable-mixin-1.0.3

    fix(package): update can-observ… (compare)

  • Oct 18 19:08
    cherifGsoul labeled #5390
  • Oct 18 19:07
    cherifGsoul opened #5390
  • Oct 18 18:45
    greenkeeper[bot] labeled #5389
  • Oct 18 18:45
    greenkeeper[bot] opened #5389
  • Oct 18 18:45

    greenkeeper[bot] on can-observable-bindings-1.3.0

    fix(package): update can-observ… (compare)

  • Oct 18 18:29

    matthewp on master

    Update dist for release (compare)

  • Oct 18 18:29

    matthewp on v6.1.3

    Update dist for release 6.1.3 (compare)

  • Oct 18 17:59

    matthewp on can-observable-array-1.0.2

    (compare)

  • Oct 18 17:59

    matthewp on master

    fix(package): update can-observ… Merge pull request #5388 from c… (compare)

  • Oct 18 17:59
    matthewp closed #5388
  • Oct 18 16:46
    greenkeeper[bot] labeled #5388
  • Oct 18 16:46
    greenkeeper[bot] opened #5388
  • Oct 18 16:46

    greenkeeper[bot] on can-observable-array-1.0.2

    fix(package): update can-observ… (compare)

Brad Momberger
@bmomberger-bitovi
What kind of element is it?
Gregg Roemhildt
@roemhildtg
Its a <select> element. But its burried in a component structure. Its weird because if I set a break point there, this is the only element that actually has a length property. I don't think its typical to have an element with a .length prop...
image.png
Brad Momberger
@bmomberger-bitovi
May we see your tag HTML that creates that select?
(stache bindings included)
Gregg Roemhildt
@roemhildtg
<select {($value)}="value" class="form-select form-control" name="{{properties.name}}">
    {{#each properties.options}}
        <option value="{{value}}">{{label}}</option>
    {{/each}}
</select>
Brad Momberger
@bmomberger-bitovi
I can definitely replicate this result in a JSBin. https://jsbin.com/jiqegoxudi/edit?html,js,console,output
Let me see if I can figure out where it's happening.
Gregg Roemhildt
@roemhildtg
hm, yes the tricky part
Brad Momberger
@bmomberger-bitovi
It's not us doing this; it seems like select elements always have a numeric length.
(equal to the number of options)
So I think the safest thing to do is to check in canViewModel whether el is an instance of Node and short-circuit the arraylike test.
Gregg Roemhildt
@roemhildtg
Mmhm that makes sense
Brad Momberger
@bmomberger-bitovi
Though, could you paste in a stack trace and the conditions where it throws? I am not seeing errors thrown in the JSBin when rendering or changing the select value
Gregg Roemhildt
@roemhildtg
Its quite a large stack trace, I'll make a pastebin
You have to call canViewModel on that element. Then it throws the error
Although I'm not calling canViewModel directly, can-stache-bindings does in the data method
Brad Momberger
@bmomberger-bitovi
Just FYI, it should be lastElementChild, as lastChild is a text node.
A-ha! I see what happened here. This is something that broke in 3.2.0 because we added support for jQueries.
There you go. You can downgrade to can-view-model 3.1.3 which doesn't do array-like or string selector checks until we get the fix in.
Gregg Roemhildt
@roemhildtg
Sweet!
Thanks for taking a look, as always :smile:
Brad Momberger
@bmomberger-bitovi
you're welcome. I'll write up an issue in Github for this as soon as I put together a JSBin not using the global dist.
Brad Momberger
@bmomberger-bitovi
The other thing I noticed is, this only breaks if you don't have any options in your select.
Gregg Roemhildt
@roemhildtg
That's something to look into...not sure why my options are empty. It must be just initially, they eventually get populated :smile:
Brad Momberger
@bmomberger-bitovi
But anyway, canjs/can-view-model#31 is up now. I'll see if someone else wants to take it on or comment
Pedro Mendes
@pmgmendes
@frank-dspeed Thanks for the hint. My issue was related to a bug that meanwhile @justinbmeyer solved.
The topic thread a test case showcasing my intention.
Thanks for the help!
gregorgodoy
@gregorgodoy
Hi everyone! I have a question about natural ids and the save method. Usually id's are generated server side by the API (surrogate key), but sometimes the id is a natural key and is specified in the app. An example could be a country list, where the id is the three-letter country code. If i create a new country instance and call the method save() it will do a PUT to the API, because save evaluates if the id attribute is present and has a value to determine if its a new instance or a already persisted instance in database. How to solve this cases? Its there a way to call explicit the createData method instead of updateData? THANKS
Brad Momberger
@bmomberger-bitovi
@gregorgodoy a common pattern we use in the model layer is to create the model definition as a subclass of DefineMap, and add the connection that maps to it as a static property on the class (we usually use the property name Connection with a capital C. Then you can explicitly call CountryModel.Connection.createData(this.serialize(), this._cid)
The other option is to override isNew() and use some other criteria than the presence of the idProp to determine whether to create or update. How will you know whether an object has been created yet or not?
gregorgodoy
@gregorgodoy

@bmomberger-bitovi thanks for your reply and suggestions! I tried your suggestion and is almost working. For sure i misunderstood something. Here the model:

import DefineMap from 'can-define/map/';
import DefineList from 'can-define/list/';
import set from 'can-set';
import superMap from 'can-connect/can/super-map/';
import loader from '@loader';

const Multimedia = DefineMap.extend({
    seal: true
}, {
    'filename': 'string',
    'mime': 'string',
    'size': 'string',
    'original_name': 'string'
});

const algebra = new set.Algebra(
    set.props.id('filename')
);

Multimedia.List = DefineList.extend({
    '#': Multimedia
});

Multimedia.connection = superMap({
    url: {
        createData: function(param) {
            return new Promise(function(resolve,reject) {
                $.ajax({
                    url: loader.serviceBaseURL + '/multimedia',
                    type: 'POST',
                    dataType: 'json',
                    data: param,
                    headers: {
                        Prefer: 'return=representation',
                        Accept: 'application/vnd.pgrst.object+json'
                    }
                }).then(resolve, reject);
            });
        }

    },
    Map: Multimedia,
    List: Multimedia.List,
    name: 'multimedia',
    algebra
});

export default Multimedia;

and then i tried the following:

model =  new Multimedia({
    filename: '131232-2131231-23123.jpg',
    mime: 'image/jpeg',
    size: '1243',
    original_name: 'portrait.jpg'
})
model.constructor.connection.createData(model.serialize(), model._cid);

And the createData is called!! And the model is persisted in the API. GREAT!! But, immediately donejs throws an error:

Potentially unhandled rejection [2] TypeError: Cannot use 'in' operator to search for '__get' in undefined at readObservabe (http://baker:81/node_modules/can-connect/can/map/map.js:746:13)

and the exactly line is:

var readObservabe = function(instance, prop){
    if("__get" in instance) {
        if(callCanReadingOnIdRead) {
            Observation.add(instance, prop);
        }
        return instance.__get(prop);
    } else {
        if(callCanReadingOnIdRead) {
            return instance[prop];
        } else {
            return Observation.ignore(function(){
                return instance[prop];
            })();
        }
    }
};
gregorgodoy
@gregorgodoy

Before i read your answer i tried the second option. I added a "flag" property to the model instance, like this:

model =  new Multimedia({
                    filename: data.filename,
                    mime: data.mime,
                    size: data.size,
                    original_name: data.original_name
                });
model._data._new = true;

And then i overwrote the save method from can-connect/constructor/constructor.js

save: function(instance){
            var serialized = this.serializeInstance(instance);
            var id = this.id(instance);
            var self = this;
            //if(id === undefined) {
            if (id === undefined || instance._data._new) {
                // If `id` is undefined, we are creating this instance.
                // It should be given a local id and temporarily added to the cidStore
                // so other hooks can get back the instance that's being created.
                var cid = this._cid++;
                this.cidStore.addReference(cid, instance);

                // Call the data layer.
                // If the data returned is undefined, don't call `createdInstance`
                return this.createData(serialized, cid).then(function(data){
                    // if undefined is returned, this can't be created, or someone has taken care of it
                    if(data !== undefined) {
                        self.createdInstance(instance, data);
                    }
                    self.cidStore.deleteReference(cid, instance);
                    return instance;
                });
            } else {
                return this.updateData(serialized).then(function(data){
                    if(data !== undefined) {
                        self.updatedInstance(instance, data);
                    }
                    return instance;
                });
            }
        }

Note i added the condition if (id === undefined || instance._data._new) { and in the save callback i set the _new flag to false. So far its working, but i think your suggestion is more elegant! What would you suggest / recommend? THANKS!

Brad Momberger
@bmomberger-bitovi
Usually that error is thrown when the returned data from a service call isn't an object when parsed from JSON. An example being if you returned a string as a status code.
gregorgodoy
@gregorgodoy
thanks! I checked the returned data and it is a well formed json. But i will keep tracing the error. thanks!! Did you see my alternative solution?
Brad Momberger
@bmomberger-bitovi
Yes, I looked it over and am thinking about it for a moment.
Assuming that filename serves as a unique ID for your Multimedia instances, I would first set idProp in your connection options to be "filename", then I would override id() in your connection instead of save():
Brad Momberger
@bmomberger-bitovi
var configuredIdConnection = function(baseConnection) {
  return {
    id: function(instance) {
      if(instance._data._new) {
        return undefined;
      } else {
        return baseConnection.id(instance);
     }
   }
  };
};
then instead of superMap, make your own connection with the behaviors that superMap uses, and tack that function on the end as the last one.
gregorgodoy
@gregorgodoy
Thanks for the suggestions, i will try it! It looks a very elegant solution. Yes, in the example filename is the unique ID, because the data comes from another API. Maybe not the best example, but the API uses a lot of natural key, and compound natural keys. I will try it and come back soon, thanks again!
Brad Momberger
@bmomberger-bitovi
If you have compound natural keys, you should be using set algebras to define them. looks like you're doing that. Where I said to set idProp in my previous suggestions, just be sure your set algebras are correct. sorry for missing that.
gregorgodoy
@gregorgodoy
Great, undestood! I come back soon! Thanks for sharing your time :clap:
Dovid Bleier
@dbleier
@bmomberger-bitovi @justinbmeyer thanks for your suggestions at https://gitter.im/canjs/canjs?at=592d95d50a783b6c0aecc10e
https://gitter.im/canjs/canjs?at=592ef39c0ba4d59763fbb6e4 (I have been out for a few days)
in the end I overwrote getListData() and updateListData on the cacheConnection
now I am faced with another serious issue. I am currently working on an upgrade to canjs 3.0
I have this code
<can-import from="cms/sign-controls/" />
<sign-controls {user}="user" {role}="role" {rolelevel}="rolelevel" {^selected-presentation}="*presentation" {^sign}="sign"></sign-controls>

<can-import from="cms/presentation-workspace/" />
<presentation-workspace {presentation}="*presentation"></presentation-workspace>
which works fine in can 2.x
the presentation is selected in the sign-controls component and passed to the presentation-workspace component where it updates a bunch of subcomponents
the problem is when I select a presentation, it does update the presentation-workspace but then creates such a memory leak, it freezes the tab and I have to kill the tab