Service for making AJAX requests in Ember applications.
- customizable service
- returns RSVP promises
- improved error handling
- ability to specify request headers
ember-ajax is now deprecated. Please consider using ember-fetch, or ember-ajax-fetch as a more direct replacement.
If you're just starting out, you already have ember-ajax installed! However, if it's missing from your package.json, you can add it by doing:
ember install ember-ajaxTo use the ajax service, inject the ajax service into your route or component.
importEmberfrom'ember';exportdefaultEmber.Route.extend({ajax: Ember.inject.service(),model(){returnthis.get('ajax').request('/posts');}});The AJAX service provides methods to be used to make AJAX requests, similar to
the way that you would use jQuery.ajax. In fact, ember-ajax is a wrapper
around jQuery's method, and can be configured in much the same way.
In general, you will use the request(url, options) method, where url is the
destination of the request and options is a configuration hash for
jQuery.ajax.
importEmberfrom'ember';exportdefaultEmber.Controller.extend({ajax: Ember.inject.service(),actions: {sendRequest(){returnthis.get('ajax').request('/posts',{method: 'POST',data: {foo: 'bar'}});}}});In this example, this.get('ajax').request() will return a promise with the
result of the request. Your handler code inside .then or .catch will
automatically be wrapped in an Ember run loop for maximum compatibility with
Ember, right out of the box.
You can skip setting the method or type keys in your options object when
calling request(url, options) by instead calling post(url, options),
put(url, options), patch(url, options) or del(url, options).
post('/posts',{data: {title: 'Ember'}});// Makes a POST request to /postsput('/posts/1',{data: {title: 'Ember'}});// Makes a PUT request to /posts/1patch('/posts/1',{data: {title: 'Ember'}});// Makes a PATCH request to /posts/1del('/posts/1');// Makes a DELETE request to /posts/1ember-ajax allows you to specify headers to be used with a request. This is
especially helpful when you have a session service that provides an auth token
that you have to include with the requests to authorize your requests.
To include custom headers to be used with your requests, you can specify
headers hash on the Ajax Service.
// app/services/ajax.jsimportEmberfrom'ember';importAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({session: Ember.inject.service(),headers: Ember.computed('session.authToken',{get(){letheaders={};constauthToken=this.get('session.authToken');if(authToken){headers['auth-token']=authToken;}returnheaders;}})});Headers by default are only passed if the hosts match, or the request is a relative path.
You can overwrite this behavior by either passing a host in with the request, setting the
host for the ajax service, or by setting an array of trustedHosts that can be either
an array of strings or regexes.
// app/services/ajax.jsimportEmberfrom'ember';importAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({trustedHosts: [/\.example\./,'foo.bar.com']});The namespace property can be used to prefix requests with a specific url namespace.
// app/services/ajax.jsimportEmberfrom'ember';importAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({namespace: '/api/v1'});request('/users/me') would now target /api/v1/users/me
If you need to override the namespace for a custom request, use the namespace as an option to the request methods.
// GET /api/legacy/users/merequest('/users/me',{namespace: '/api/legacy'});ember-ajax allows you to specify a host to be used with a request. This is
especially helpful so you don't have to continually pass in the host along
with the path, makes request() a bit cleaner.
To include a custom host to be used with your requests, you can specify host
property on the Ajax Service.
// app/services/ajax.jsimportEmberfrom'ember';importAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({host: 'http://api.example.com'});That allows you to only have to make a call to request() as such:
// GET http://api.example.com/users/merequest('/users/me');ember-ajax allows you to specify a default Content-Type header to be used with a request.
To include a custom Content-Type you can specify contentType property on the Ajax Service.
// app/services/ajax.jsimportEmberfrom'ember';importAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({contentType: 'application/json; charset=utf-8'});You can also override the Content-Type per request with the options parameter.
Some APIs respond with status code 200, even though an error has occurred and
provide a status code in the payload. With the service, you can easily account
for this behaviour by overwriting the isSuccess method.
// app/services/ajax.jsimportAjaxServicefrom'ember-ajax/services/ajax';exportdefaultAjaxService.extend({isSuccess(status,headers,payload){letisSuccess=this._super(...arguments);if(isSuccess&&payload.status){// when status === 200 and payload has status property,// check that payload.status is also considered a success requestreturnthis._super(payload.status);}returnisSuccess;}});ember-ajax provides built in error classes that you can use to check the error
that was returned by the response. This allows you to restrict determination of
error result to the service instead of sprinkling it around your code.
ember-ajax has built-in error types that will be returned from the service in the event of an error:
BadRequestError(400)UnauthorizedError(401)ForbiddenError(403)NotFoundError(404)InvalidError(422)ServerError(5XX)AbortErrorTimeoutError
All of the above errors are subtypes of AjaxError.
ember-ajax comes with helper functions for matching response errors to their respective ember-ajax error type. Each of the errors listed above has a corresponding is* function (e.g., isBadRequestError).
Use of these functions is strongly encouraged to help eliminate the need for boilerplate error detection code.
importEmberfrom'ember';import{isAjaxError,isNotFoundError,isForbiddenError}from'ember-ajax/errors';exportdefaultEmber.Route.extend({ajax: Ember.inject.service(),model(){constajax=this.get('ajax');returnajax.request('/user/doesnotexist').catch(function(error){if(isNotFoundError(error)){// handle 404 errors herereturn;}if(isForbiddenError(error)){// handle 403 errors herereturn;}if(isAjaxError(error)){// handle all other AjaxErrors herereturn;}// other errors are handled elsewherethrowerror;});}});If your errors aren't standard, the helper function for that error type can be used as the base to build your custom detection function.
If you need to access the json response of a request that failed, you can use the raw method instead of request.
this.get('ajax').raw(url,options).then(({ response })=>this.handleSuccess(response)).catch(({ response, jqXHR, payload })=>this.handleError(response));Note that in this use case there's no access to the error object. You can inspect the jqXHR object for additional information about the failed request. In particular jqXHR.status returns the relevant HTTP error code.
Ember AJAX provides a mixin that can be used in an Ember Data Adapter to avoid the networking code provided by Ember Data and rely on Ember AJAX instead. This serves as a first step toward true integration of Ember AJAX into Ember Data.
To use the mixin, you can include the mixin into an Adapter, like so:
// app/adapters/application.jsimportDSfrom'ember-data';importAjaxServiceSupportfrom'ember-ajax/mixins/ajax-support';exportdefaultDS.JSONAPIAdapter.extend(AjaxServiceSupport);That's all the configuration required! If you want to customize the adapter, such as using an alternative AJAX service (like one you extended yourself), hooks to do so are provided; check out the mixin's implementation for details.
Note that instead of using the Ember Data error checking code in your application, you should use the ones provided by Ember AJAX.
If you aren't using Ember Data and do not have access to services, you can import the ajax utility like so:
importrequestfrom'ember-ajax/request';exportdefaultfunctionsomeUtility(url){varoptions={// request options};returnrequest(url,options).then(response=>{// `response` is the data from the serverreturnresponse;});}Which will have the same API as the ajax service. If you want the raw jQuery XHR object
then you can use the raw method instead:
importrawfrom'ember-ajax/raw';exportdefaultfunctionsomeOtherUtility(url){varoptions={// raw options};returnraw(url,options).then(result=>{// `result` is an object containing `response` and `jqXHR`, among other itemsreturnresult;});}This information is only relevant if you're looking to contribute to ember-ajax.
- Node.js 6 or above
- Ember CLI v2.13 or above
git clonethis repositorynpm install
ember server- Visit your app at http://localhost:4200.
ember testember test --server
ember build
For more information on using ember-cli, visit http://www.ember-cli.com/.