Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS code gen: Using Promises and non-jquery ajax #2014

Closed
delenius opened this issue Feb 1, 2016 · 13 comments
Closed

JS code gen: Using Promises and non-jquery ajax #2014

delenius opened this issue Feb 1, 2016 · 13 comments

Comments

@delenius
Copy link
Contributor

delenius commented Feb 1, 2016

This is a couple of feature requests for the JavaScript client generator (not the runtime generator, I am generating form a swagger file offline):

  1. Is there any way to make the generator produce a JS client produce a client that uses Promises? It looks like the online generator can do this, but not the offline one, but I could be wrong.

  2. Is there any chance we could get rid of jQuery to do the ajax calls? It is unfortunate to have to pull in this heavy dependency just for that, when there are many lightweight ajax libraries out there. Ideally it should work both in a Web client and from Node, so how about something like isomorphic-fetch? This also uses Promises, so it helps with Adds the missing install-ivy build script #1 above.

@wing328
Copy link
Contributor

wing328 commented Feb 2, 2016

@delenius are you generating the client with -l javascript using the latest master? The latest one uses https://github.com/visionmedia/superagent, which might meet your need.

@wing328 wing328 added this to the v2.1.6 milestone Feb 2, 2016
@delenius
Copy link
Contributor Author

delenius commented Feb 2, 2016

That looks pretty nice, except for the fact that it doesn't use standard promises. I'll give it a shot anyway.

@wing328
Copy link
Contributor

wing328 commented Feb 2, 2016

@delenius please review and feel free to suggest changes related to using Promises

@delenius
Copy link
Contributor Author

delenius commented Feb 2, 2016

@wing328 do you mean suggest changes to this project or to the superagent project?

@wing328
Copy link
Contributor

wing328 commented Feb 3, 2016

I mean this project.

@delenius
Copy link
Contributor Author

delenius commented Feb 3, 2016

I guess you could provide a usePromise configuration flag. When true, the generated API methods would not take a callback parameter. Instead, you would change the handleResponse functions to resolve/reject the promise. Currently, you generate something like this:

      // bunch of stuff

      var handleResponse = null;
      if (callback) {
        handleResponse = function(error, data, response) {
          callback(error, data, response);
        };
      }

      return this.apiClient.callApi(
        '/', 'GET',
        pathParams, queryParams, headerParams, formParams, postBody,
        contentTypes, accepts, handleResponse
      );

instead, you could do

      // bunch of stuff

      return new Promise(function(resolve,reject) {
        var handleResponse = function(error, data, response) {
          error ? reject(error) : resolve(data);
        };

        this.apiClient.callApi(
          '/', 'GET',
          pathParams, queryParams, headerParams, formParams, postBody,
          contentTypes, accepts, handleResponse
        );        
      });

which would allow the caller to call the usual then() and catch() methods on the returned promise.

@wing328
Copy link
Contributor

wing328 commented Feb 3, 2016

Thanks for the suggestion. Would you have cycle to submit a PR with the suggested change?

@xhh
Copy link
Contributor

xhh commented Feb 3, 2016

@delenius Thanks for the suggestions. The reason I didn't use Promise is that it is a feature of ES6 which is only supported by modern browsers.

For controlled environments where Promise is known to be supported, it would be easy to convert an API call to a Promise. Maybe it would be helpful to add a helper function for it. For example:

// helper function
function makeCallback(resolve, reject) {
  return function (error, data, response) {
    if (error) {
      reject(error);
    } else {
      resolve([data, response]);
    }
  };
}

// use the helper function
var p = new Promise((resolve, reject) => {
  petApi.getPetById(1, makeCallback(resolve, reject));
});
p.then(([pet, response]) => {
  console.log('Pet:', pet);
});

Another possible helper function:

// PetApi.js

PetApi.prototype.callWithPromise = function (methodName, ...args) {
  return new Promise((resolve, reject) => {
    this[methodName](...args, makeCallback(resolve, reject));
  });
};

// use the helper method
var p = petApi.callWithPromise('getPetById', 1);
p.then(([pet, response]) => {
  console.log('Pet:', pet);
});

With that said, we could just generate additional functions to return Promise, e.g.

var p = petApi.getPetByIdWithPromise(1);

Any ideas?

@delenius
Copy link
Contributor Author

delenius commented Feb 3, 2016

There are polyfills to support Promise on older browsers. It would be cleanest to not have to invoke a bunch of additional stuff just to get the promises. After all, the "online" JS generator has a "usePromise" parameter along these lines.

@wing328
Copy link
Contributor

wing328 commented Feb 3, 2016

For the "online" JS generator, do you mean https://editor.swagger.io?

@wing328
Copy link
Contributor

wing328 commented Feb 3, 2016

@delenius
Copy link
Contributor Author

delenius commented Feb 3, 2016

@wing328 yes that one :)

@delenius
Copy link
Contributor Author

delenius commented Feb 4, 2016

For the record, there is superagent-promise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants