ember.js RestAdapter How to define ajaxoptions - mongodb

I customized RESTAdapter to connect to a RestHeart server (a RestFull web
gateway server for mongodb):
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host:'http://127.0.0.1:8080',
namespace: 'boards'
});
I created a model to test :
import DS from 'ember-data';
export default DS.Model.extend({
identity: DS.attr()
});
Everything works fine, but when I use the save method on a record (developer):
I have a warning in the browser console :
The server returned an empty string for POST
http://.../boards/Developer, which cannot be parsed into a valid JSON.
Return either null or {}.
and the folowing error :
SyntaxError: Unexpected end of JSON input
at parse ()
at ajaxConvert (jquery.js:8787)
at done (jquery.js:9255)
at XMLHttpRequest. (jquery.js:9548)
I know why :
The RESTAdapter is waiting for a JSON response, and the restHeart server returns an empty response when adding => so jQuery causes an error when it tries to parse the null response.
With previous versions of ember-data, it was possible to set the dataType variable of jQuery ajax requests to '*' using the hook ajaxOptions this way:
export default DS.RESTAdapter.extend({
ajaxOptions(url, type, options) {
var hash = this._super(url, type, options);
hash.dataType = "*";
return hash;
},
host:'http://127.0.0.1:8080',
namespace: 'boards'
});
With ember-data 2.16, ajaxOptions is now private, and I do not know how to modify the dataType variable... so that the null response is not parsed as a JSON response
Versions :
ember-data 2.16
ember 2.18

Solution found
export default DS.RESTAdapter.extend({
ajaxOptions: function(url, type, options) {
// get the default RESTAdapter 'ajaxOptions'
var hash = this._super(url, type, options);
// override if it's a POST request
if (type == 'POST') {
hash.dataType = 'text';
}
return hash;
},
ajaxSuccess: function(jqXHR, data) {
if (typeof data === 'string') {
// return an empty object so the Serializer handles it correctly
return {};
} else {
return data;
}
},
host:'http://127.0.0.1:8080',
namespace: 'boards'
});
It works without any warning or error,strangely,
because I don't know if I respect the encapsulation of the RESTAdapter class ...
see Ember-data 2.6 & 2.7 release notes

Related

I wana have my application to fetch a html web page but i keep getting -400 whatever i try monkey c / garmin connect

even this exemple i found on the site of garmin has the same problem
https://developer.garmin.com/connect-iq/core-topics/https/
import Toybox.System;
import Toybox.Communications;
import Toybox.Lang;
class JsonTransaction {
// set up the response callback function
function onReceive(responseCode as Number, data as Dictionary?) as Void {
if (responseCode == 200) {
System.println("Request Successful"); // print success
} else {
System.println("Response: " + responseCode); // print response code
}
}
function makeRequest() as Void {
var url = "https://www.garmin.com"; // set the url
var params = { // set the parameters
"definedParams" => "123456789abcdefg"
};
var options = { // set the options
:method => Communications.HTTP_REQUEST_METHOD_GET, // set HTTP method
:headers => { // set headers
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED},
// set response type
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED
};
var responseCallback = method(:onReceive); // set responseCallback to
// onReceive() method
// Make the Communications.makeWebRequest() call
Communications.makeWebRequest(url, params, options, method(:onReceive));
}
}
can some one please tel me what i am doing wrong
The return code -400 means "Response body data is invalid for the request type." according to the SDK specification.
You are requesting a response type of Communications.HTTP_RESPONSE_CONTENT_TYPE_URL_ENCODED but in your question you state that you are expecting HTML to be returned, which almost certainly can't be parsed as URL encoded form parameters.
The SDK does not seem to support HTML response types. Even if you omit the expected response type, the server will probably still send "application/html" and the SDK states that "If the Content-Type header from the response is not one of the known HTTP_RESPONSE_CONTENT_TYPE_* types, an error will occur", so I guess you're out of luck.
Maybe you can try to request HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN in order to get the server to return text instead of HTML, which you then could use somehow?

Sending POST requests to a nested API endpoint URL using Ember Data

I see several questions on SO attempting to solve this problem of sending POST requests to nested API resource routes.
See:
- [Sending REST requests to a nested API endpoint URL using Ember Data(Sending REST requests to a nested API endpoint URL using Ember Data)
- Custom request URLs in Ember model
I've started overloading the createRecord, updateRecord, and deleteRecord methods on the RESTAdapter to attempt some sort of hackery solution to building the correct URL. Now, using a method similar to this is the route I've taken so far.
Here is the updateRecord method in their solution:
App.UserAdapter = DS.RESTAdapter.extend({
updateRecord: function(store, type, record) {
if(!record.get('parent') || null === record.get('parent')){
return this._super(store, type, record);
}
var data = {};
var serializer = store.serializerFor(type.typeKey);
var parent_type = record.get('parent');
var parent_id = record.get(parent_type).get('id');
var child_parts = Ember.String.decamelize(type.typeKey).split('_');
var path = Ember.String.pluralize(parent_type) + '/' + parent_id + '/' + Ember.String.pluralize(child_parts.pop());
serializer.serializeIntoHash(data, type, record);
var id = record.get('id');
return this.ajax(this.buildURL(path, id), "PUT", { data: data });
}
....
});
This method should work great in tandem with adding the parent type to the model and ensuring the related parent model id is also represented on the model. For PUT and DELETE requests, this shouldn't be a problem, as we already have the parent ID relation on the object in store.
Project model:
App.ProjectModel = DS.Model.extend({
name: DS.attr('string'),
createdAt: DS.attr('date'),
updatedAt: DS.attr('date'),
workspace : DS.belongsTo('workspace'),
parent: 'workspace',
....
});
Where this method appears to go awry for me is in creating new resources with a post. I've attempted it, but since the payload hasn't been returned from the API server with the related parent ID, I actually don't have access to it.
Here's my crappy first attempt, that doesn't work. The workspace id always returns null.
createRecord: function(store, type, record) {
if (!record.get('parent') || null === record.get('parent')){
return this._super(store, type, record);
}
var data = {};
var serializer = store.serializerFor(type.typeKey);
var parent_type = record.get('parent');
var parent_id = record.get(parent_type).get('id');
var path = Ember.String.pluralize(parent_type) + '/' + parent_id + '/' + type.typeKey);
serializer.serializeIntoHash(data, type, record, { includeId: true });
return this.ajax(this._buildURL(path, null), "POST", { data: data });
},
Got any thoughts on how I can get the parent ID, before I have a saved record?
I am the author of the solution you cited in your question.
What does your model hook look like in the route where you are creating the new ProjectModel?
Assuming your Workspace route looks something like:
App.WorkspaceRoute = Ember.Route.extend({
model: function (params) {
return this.store.find('workspace', params.id);
}
});
Then your Workspace Project add/create route's model hook would need to be something like:
App.WorkspaceProjectAddRoute = Ember.Route.extend({
model: function () {
var workspace = this.modelFor('workspace');
return this.store.createRecord('project', {
workspace: workspace
});
}
}
I hope this makes some sense...

PUT request returning a 400 Bad Request Error

I am doing a PUT request to RESTfull service which changes password of a user. For the time being I have just hardcoded values of new and old password in my AJAX test my service. However it is giving me a 400 error.
AJAX call
$.ajax({
type: "PUT",
url: "api/teachers/"+user,
data: {"old":"123","new":"qwe"},
contentType: "application/json",
success: function(data,status)
{
datax = data;
alert(data+status);
ko.applyBindings(new AddMarkSheetKo(data));
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert(XMLHttpRequest+textStatus+ errorThrown);
// error handler here
}
});
Restful function:
#PUT
#Path("/{name}")
#Consumes(MediaType.APPLICATION_JSON)
public Response changePwd(#PathParam ("name")String name,#QueryParam ("old") String old, #QueryParam("new") String nw){
System.out.println("entered function"+old+nw);
Teacher t = DataAccessUtil.getByName(Teacher.class, name);
if(t.getPassword().equals(old)){
t.setPassword(nw);
DataAccessUtil.update(t);
return Response.ok().build();
}
else{
return Response.status(Status.BAD_REQUEST).entity("Wrong password !!!").build();
}
//return reposnse;
}
This information might be useful that on the console it prints
entered functionnullnull
So it the restfull function is called however it is not receiving the query parameters.
Any help would be really appreciated!
First, you could replace the #QueryParam annotations with #FormParam ones to retrieve the 'new' and 'old' parameters of the PUT request. Then, you should remove the #Consumes("application/json") annotation and contentType:application/json from your server and browser side code, and finally replace the submitted data in JSON format into something like 'new=qwe&old=123'.
If you want to stay with a content in JSON format, you should probably map the incoming body with an entity (ie, a Java class annotated with JAXB annotations), so that the JAX-RS implementation you use could unmarshall the incoming JSON content into a Java object.
HTH.

How to get the REST response message in ExtJs 4?

I'm building upon RESTFul Store example of ExtJs 4. I'd like my script to display errors provided by the REST server, when either Add or Delete request fails. I've managed to obtain the success status of a request (see the code below), but how do I reach the message provided with the response?
Store:
var store = Ext.create('Ext.data.Store', {
model: 'Users',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
url: 'test.php',
reader: {
type: 'json',
root: 'data',
model: 'Users'
},
writer: {
type: 'json'
},
afterRequest: function(request, success) {
console.log(success); // either true or false
},
listeners: {
exception: function(proxy, response, options) {
// response contains responseText, which has the message
// but in unparsed Json (see below) - so I think
// there should be a better way to reach it than
// parse it myself
console.log(proxy, response, options);
}
}
}
});
Typical REST response:
"{"success":false,"data":"","message":"VERBOSE ERROR"}"
Perhaps I'm doing it all wrong, so any advice is appreciated.
I assume that your service follows the REST principle and uses HTTP status codes other than 2xx for unsuccessful operations.
However, Ext will not parse the response body for responses that do not return status OK 2xx.
What the exception/response object (that is passed to 'exception' event listeners) does provide in such cases is only the HTTP status message in response.statusText.
Therefore you will have to parse the responseText to JSON yourself. Which is not really a problem since it can be accomplished with a single line.
var data = Ext.decode(response.responseText);
Depending on your coding style you might also want to add some error handling and/or distinguish between 'expected' and 'unexpected' HTTP error status codes. (This is from Ext.data.reader.Json)
getResponseData: function(response) {
try {
var data = Ext.decode(response.responseText);
}
catch (ex) {
Ext.Error.raise({
response: response,
json: response.responseText,
parseError: ex,
msg: 'Unable to parse the JSON returned by the server: ' + ex.toString()
});
}
return data;
},
The reason for this behavior is probably because of the REST proxy class not being a first class member in the data package. It is derived from a common base class that also defines the behavior for the standard AJAX (or JsonP) proxy which use HTTP status codes only for communication channel errors. Hence they don't expect any parsable message from the server in such cases.
Server responses indicating application errors are instead expected to be returned with HTTP status OK, and a JSON response as posted in your question (with success:"false" and message:"[your error message]").
Interestingly, a REST server could return a response with a non-2xx status and a response body with a valid JSON response (in Ext terms) and the success property set to 'true'. The exception event would still be fired and the response body not parsed.
This setup doesn't make a lot of sense - I just want to point out the difference between 'success' in terms of HTTP status code compared to the success property in the body (with the first having precedence over the latter).
Update
For a more transparent solution you could extend (or override) Ext.data.proxy.Rest: this will change the success value from false to true and then call the standard processResponse implementation. This will emulate 'standard' Ext behavior and parse the responseText. Of course this will expect a standard JSON response as outlined in your original post with success:"false" (or otherwise fail).
This is untested though, and the if expression should probably be smarter.
Ext.define('Ext.ux.data.proxy.Rest', {
extend: 'Ext.data.proxy.Rest',
processResponse: function(success, operation, request, response, callback, scope){
if(!success && typeof response.responseText === 'string') { // we could do a regex match here
var args = Array.prototype.slice.call(arguments);
args[0] = true;
this.callParent(args);
} else {
this.callParent(arguments);
}
}
})

zend get with jQuery $.getJson

Does anyone know how to do this?
I want to point $.getJson() to a controller and have it return json through ajax based on request arguments. Unfortunately it appears Zend handles the get parameters different than jQuery encodes them.
How can I do this with Zend and jQuery? I saw something on stackoverflow about Post arguments but I am lost when it comes to GET.
When using jQuery I get a 404 error using this code:
Client side:
$.getJSON("/entry/get-member-course",
{
"id": 1,
"format": "json"
},
function(json) {
alert("WIN");
});
Server side:
public function init() {
$this->_helper->ajaxContext->addActionContext('get-member-course', 'json')->initContext();
}
public function getMemberCourseAction() {
$this->view->test = Array("test"=>"bleh");
}
Easiest way is to use context switching. In your controller, setup the AjaxContext helper for your action with a "json" context
class EntryController extends Zend_Controller_Action
{
public function init()
{
$this->_helper->ajaxContext->addActionContext('get-member-course', 'json')
->initContext();
}
public function getMemberCourseAction()
{
$id = $this->_getParam('id');
$this->view->test = array('test' => 'bleh');
}
}
The view for the calling script should contain a reference to the JSON URL. For example, say your JSON code is fired by clicking a link, create the link like this
<a id="get-json" href="<?php echo $this->url(array(
'action' => 'get-member-course',
'controller' => 'entry',
'id' => $someId
), null, true) ?>">Click me for JSON goodness</a>
Your client-side code would have something like this
$('#get-json').click(function() {
var url = this.href;
$.getJSON(url, {
"format": "json" // this is required to trigger the JSON context
}, function(data, textStatus, jqXHR) {
// handle response here
});
});
By default, when the JSON context is triggered, any view property is serialized as JSON and returned in the response. If your view properties cannot be simply converted, you need to disable automatic JSON serialization...
$this->_helper->ajaxContext->addActionContext('my-action', 'json')
->setAutoJsonSerialization(false)
->initContext();
and provide a JSON view script
// controllers/my/my-action.json.phtml
$simplifiedArray = array(
'prop' => $this->someViewProperty->getSomeValue()
);
echo Zend_Json::encode($simplifiedArray);
getJSON encodes a JSON string sequences such as {Person:{name: "Ken", age: "24"}}, do you have corresponding decoder on your server side?
JSON PHP
Zend PHP JSON