How to force POST on Collection.commit()?

Hi Enyo folks,
I found a couple of references to this situation, but no solution I really understand...
I have an API that will reject any PUT with an array of objects, but will accept such an array with a POST.

I have tried overloading the collection's AjaxSource with:
commit: function (model, opts) {<br />  this.inherited(arguments);<br />  opts.method = 'POST';<br />  console.log('in posty commit, opts = ' + JSON.stringify(opts));<br />},
That does log that the method should be POST:
>in posty commit, opts = {"method":"POST","url":"...","postBody":...
...but in Firefox it is still PUTting...
If I edit and resend in Firefox - just changing the verb to POST - it goes through, but I can't figure out how to make Enyo POST this commit.

Comments

  • My guess is its running the overloaded functions code before it even gets to yours.
    When you call this.inherited, it calls the overloaded function first, then does the code below it. So it is probably doing the call before it touches your changes.

    I usually just replace that function in my sources. Copy the original function from the source, and then change it for how i need it to behave.
  • Wow! @chrisvanhooser - Huge help! I never got that trick before - works like a charm to just do:
        commit: function (model, opts) {<br />      opts.method = 'POST'; // Only change from source<br />      opts.url = this.buildUrl(model, opts);<br />      opts.postBody = opts.postBody || model.toJSON();<br />      this.go(opts);<br />    },
    -Thanks so much!!!
  • Glad you found a solution! There's a bit of risk in copying framework code since we might change things out from under you. You're pretty safe in this case but as a general rule it should be avoided.

    AjaxSource is pretty specific about its RESTful-ness so it doesn't have API for overriding the method for commits. An alternative to copy/paste here would be to override go() to set the method to POST when it's PUT.
    go: function (opts) {<br />  if (opts.method === 'PUT') {<br />    opts.method = 'POST';<br />  }<br /><br />  return this.inherited(arguments);<br />}
  • edited April 19
    Thanks for the reply @theryanjduffy , I'll give that a whirl as well.

    I'm guessing that the problem stems from something else I'm doing wrong, because it seems that to be RESTful a collection created by Collection.add on the client side should do a POST on commit... But I did come across a few posts about isNew / States.NEW not being set properly in certain scenarios which is what I suppose I'm running into.
  • @theryanjduffy , looking at this a bit more, it seems to me that the current status/State check for AjaxSource.commit forces PUT when it should use POST. https://github.com/enyojs/enyo/blob/master/src/AjaxSource.js#L77
    opts.method = (model.status & States.NEW) ? 'POST': 'PUT';

    I load a collection with new models via Collection.add(new TaskModel({collectionId: i, description: 'desc' + i, name: ...});

    When I commit model.status resolves to 32 and States.NEW resolves to 1.

    (model.status & States.NEW) resolves to 0 and chooses 'PUT' although a model.status of 32 indicates "COMMITTING"
    http://enyojs.com/docs/latest/#/module/enyo/States:COMMITTING
    and States.NEW is true.

    It seems that during commit a model.status of 32 ("COMMITTING") and a States.NEW of true should choose 'POST' ... No?
  • edited April 20
    Too late to edit, but here's a fiddle:
    http://jsfiddle.net/buckbito/e7d36ako/

    Directly before calling commit, Collection.get("status") gets -2041 (which would choose 'POST' in opts.method = (model.status & States.NEW) ? 'POST': 'PUT';), but once we're actually in the commit in AjaxSourcemodel.status goes to 32 so 'PUT' is chosen...
Sign In or Register to comment.