Error when invoking Worklight HTTP Adapter - json

I am developing in Worklight 5.0.6. I have created an HTTP adapter. On my server side, I have a php script that accepts a parameter from the URL, performs a check on the data using php, and then returns a JSON Object back.
When I go to the actual page, It returns data like this:
[{"SUCCESS": "888888888"}]
Now, when I run my HTTP Adapter, I get these results:
errors: Class Cast: java.lang.String cannot be cast to org.mozilla.javascript.Scriptable
I've tried to change the returned Content type to text, plain, JSON, json/application and none of those options work. How do I need to return the data from the server so that the HTTP adapter can read it or what changes do I need to make to the HTTP Adapter?
method : 'get',
returnedContentType : 'plain',
path : path,
headers: 'accepts: */*',
parameters : {
'myparam' : param,
}
};
return WL.Server.invokeHttp(input);

Wrap your json array in an object. Worklight can't handle returning arrays :(

Related

How to: (a) send JSON data from the browser to the controller; and (b) send the transformed data to SQL Server within ASP.NET MVC?

I have a form which includes a variety of <input> elements and makes use of 1-to-n tabulator tables for data input. I have managed to successfully assemble data from these elements into a JSON string. I am now attempting to complete the following two steps:
Using Ajax, post the JSON object to my web server; and
In the ASP.NET MVC controller, upload the deserialized JSON data into a SQL Server 2016 table.
My client-side script to POST the JSON object is as follows:
var myJson = "the data from the form elements is programmatically inserted into the JSON string";
// use parseJSON() to test the syntax
try {
var obj = jQuery.parseJSON(myJson);
}
catch(error) {
console.log(error);
}
$.ajax({
type: "POST",
url: "/Dailies/UploadJson/",
dataType: 'json',
data: JSON.stringify(myJson),
contentType: 'application/json',
crossDomain: true,
cache: false,
success: function(data) { console.log(data); }
});
The method called within my ASP.NET MVC controller appears as follows:
[HttpPost]
public IActionResult UploadJson(Object jsonFile)
{
// insert data into SQL Server table
}
Note: I have already created the appropriate domain model within my ASP.NET MVC app and have also added a DbSet reference to the DbContext model. I have verified my ability to insert rows into the SQL Server table using mock data.
When I place a breakpoint inside the UploadJson() method, I find that the jsonFile object is null.
My quandry at this point is two-fold:
I can't seem to get JSON data from the client to the web server; and
I need to better understand how to transform the JSON data (once received) for upload into my database.
Any assistance is greatly appreciated.
Although there are plenty of questions related to this, the answers to those typically refer to binding to a model instead of just the json string. But those will also help you.
It looks like there are two things:
I would change the controller to receive a string instead of an object.
You'll need to update the json data you're passing to the controller to match the parameter name of the controller. So in this case, the controller would receive a parameter named jsonFile. So in the $.ajax method you'll want update the data to something like:
data: { jsonFile: JSON.stringify(myJson) }
UPDATE:
remove the Content-Type of application/json

How to parse JSON object at server side?

I am trying to send data to a server (local rest API) from react using post request, if i send an object like this:
{key:"value"}
then i get this at the server:
{ '{"key":"value"}': '' }
It's converting the whole object into key-value pair.
How can i solve this issue?
axios.post('http://localhost:5000/animals', JSON.stringify(data))
.then((response)=>{
console.log(response);
});
If I don't stringify, then I get an empty object at the server, but if I do stringify, then I get this sort of object as mentioned above. Is there any way to convert it back to a normal object?
It looks like the server expects to get data in application/x-www-form-urlencoded encoding, not application/json.
Why?
application/x-www-form-urlencoded encoded data looks like
key1=value1&key2=value2&....
But values are optional, so
key1&key2=value2
works too.
You are sending {"key":"value"} which to the server looks like a key without a value. Since it looks like you have control over the server, change the server implementation to parse the request body as JSON instead. How to do that depends on the framework you are using on the server.
If you are using express.js, use bodyParser.json(). Alternatively send the data application/x-www-form-urlencoded encoded, not as JSON, as suggested by Chinedu.
Performing a POST request with axios
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Can you try constructing the data you want to send as the above exam, send to your api and see if the dummy data comes. No json parse or stringfy needed.
Are you using body-parser middleware in your nodejs express app?

NodeJS and HTTP: How to send JSON content in a POST/PUT call as a string rather than creating a new key

I built an API service that will process REST requests and use them to perform CRUD operations on a MongoDB instance. This application is standalone (by design) and should be a passthrough for anything that calls it. My other application that I built in Angular is calling this API to interact with my MongoDB instance. I have been trying to construct my JSON payload from a form, which works fine. I get something like:
{ "_id":"111111111", "name":"herp", "address":"derp", "city":"foo", "state":"bar", "zip":"11111", "phone":"111-222-3333"}
I am then trying to take that JSON and send it along to the service, but something is getting lost in translation once the service gets a hold of it and my variable name that contains the JSON object is being turned into an actual key in the request, with the JSON as its value. I am calling the service like this:
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Cache-Control': 'no-cache' })
};
updateStuff(update){
console.log("Sending: " + JSON.stringify(update) + " for update");
return this.http.put('http://localhost:3000/api/test/_update', {dbName:"testDb",collection:"testing",update}, httpOptions);
}
Which logs:
Sending: {"name":"blah","address":"111 Anystreet","city":"MyCity","state":"NY","zip":"11111","phone":"555-111-2222","_id":"5ba914df13236f7a6ea3e233"} for update
So I know that right before the call is made, the data is fine. However, on the other side, it sees the following when it gets the data:
Received request: {"dbName":"testDb","collection":"testing","update":{"name":"blah","address":"111 Anystreet","city":"MyCity","state":"NY","zip":"11111","phone":"555-111-2222","_id":"5ba914df13236f7a6ea3e233"}}
instead of what I intended, which is below:
{"dbName":"testDb","collection":"testing","name":"blah","address":"111 Anystreet","city":"MyCity","state":"NY","zip":"11111","phone":"555-111-2222","_id":"5ba914df13236f7a6ea3e233"}
How do I tell the HTTP request to send the data itself rather than constructing a new key with the name "update" and sticking the payload in there as its value? I tried JSON.stringify, but that ends up sending the same thing, but with a bunch of backslashes in front of all the parenthesis. It still sends it all in a key with the name "update" as well. Any help would be greatly appreciated.
Your problem is here:
{dbName:"testDb",collection:"testing",update}
The statement above is shorthand for this:
{dbName:"testDb",collection:"testing",update:update}
What you're looking to do is this:
{dbName:"testDb",collection:"testing",...update}
Which is shorthand for this:
const data = {dbName:"testDb",collection:"testing"};
for (let key in update) {
if (update.hasOwnProperty(key)) {
data[key] = update[key];
}
}

Angular resource 404 Not Found

I've read other posts that have similar 404 errors, my problem is that I can correctly query the JSON data, but can't save without getting this error.
I'm using Angular's $resource to interact with a JSON endpoint. I have the resource object returning from a factory as follows:
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' });
});
My JSON is valid and I can successfully use resource's query() method to return the objects inside of my directive, like this:
var item = Product.query().$promise.then(function(promise) {
console.log(promise) // successfully returns JSON objects
});
However, when I try to save an item that I've updated, using the save() method, I get a 404 Not Found error.
This is the error that I get:
http://localhost:3000/api/products.json/12-34 404 (Not Found)
I know that my file path is correct, because I can return the items to update the view. Why am I getting this error and how can I save an item?
Here is my data structure:
[
{
"id": "12-34",
"name": "Greece",
"path": "/images/athens.png",
"description": ""
},
...
]
By default the $save method use the POST verb, you will need to figure out which HTTP verbs are accepted by your server en order to make an update, most modern api servers accept PATCH or PUT requests for updating data rather than POST.
Then configure your $resource instance to use the proper verb like this :
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' }, {'update': { method:'PUT' }});
});
check $resource docs for more info.
NOTE: $resource is meant to connect a frontend with a backend server supporting RESTful protocol, unless you are using one to receive data & save it into a file rather than a db.
Otherwise if you are only working with frontend solution where you need to implement $resource and have no server for the moment, then use a fake one, there is many great solutions out there like deployd.
You probably don't implement POST method for urls like /api/products.json/12-34. POST method is requested from angular for saving a new resource. So you need to update your server side application to support it and do the actual saving.
app.factory('Product', function($resource) {
return $resource('api/products.json/:id', { id: '#id' });
});
Try adding "/:id" at the end of the URL string.

PUT requests with Custom Ember-Data REST Adapter

I'm using Ember-Data 1.0.0.Beta-9 and Ember 1.7 to consume a REST API via DreamFactory's REST Platform. (http://www.dreamfactory.com).
I've had to extend the RESTAdapter in order to use DF and I've been able to implement GET and POST requests with no problems. I am now trying to implement model.save() (PUT) requests and am having a serious hiccup.
Calling model.save() sends the PUT request with the correct data to my API endpoint and I get a 200 OK response with a JSON response of { "id": "1" } which is what is supposed to happen. However when I try to access the updated record all of the properties are empty except for ID and the record on the server is not updated. I can take the same JSON string passed in the request, paste it into the DreamFactory Swagger API Docs and it works no problem - response is good and the record is updated on the DB.
I've created a JSBin to show all of the code at http://emberjs.jsbin.com/nagoga/1/edit
Unfortunately I can't have a live example as the servers in question are locked down to only accept requests from our company's public IP range.
DreamFactory provides a live demo of the API in question at
https://dsp-sandman1.cloud.dreamfactory.com/swagger/#!/db/replaceRecordsByIds
OK in the end I discovered that you can customize the DreamFactory response by adding a ?fields=* param to the end of the PUT request. I monkey-patched that into my updateRecord method using the following:
updateRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var adapter = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
// hack to make DSP send back the full object
adapter.ajax(adapter.buildURL(type.typeKey) + '?fields=*', "PUT", { data: data }).then(function(json){
// if the request is a success we'll return the same data we passed in
resolve(json);
}, function(reason){
reject(reason.responseJSON);
});
});
}
And poof we haz updates!
DreamFactory has support for tacking several params onto the end of the requests to fully customize the response - at some point I will look to implement this correctly but for the time being I can move forward with my project. Yay!
EmberData is interpreting the response from the server as an empty object with an id of "1" an no other properties in it. You need to return the entire new object back from the server with the changes reflected.