I am trying to modify object using mlab api through ajax call.Following is the code used:
query="{'email':'"+localStorage.getItem("email") +"','restore':'yes'}"
object={"$set":{'restore':"no"}}
$.ajax({
url: "https://api.mongolab.com/api/1/databases/db/collections/coll?apiKey=apiKey&q="+query,
data: JSON.stringify( object ),
type: "PUT",
contentType: "application/json"
}).done(function( restored_obj ) {
console.log(restored_obj)
})
The object gets successfully updated.The response that I receive is only the number of objects that are modified and not the modified object itself.
How do I get modified objects without making a round trip?
A PUT request to the mLab Data API will run MongoDB's update command. The update command cannot return the updated object (see the documentation here).
But you can run MongoDB's findAndModify command by posting to the /databases/<dbname>/runCommand endpoint of the mLab Data API. See the documentation for the runCommand endpoint here.
findAndModify is able to return updated objects. See the documentation here. If you set the new option to true, you will receive the newly updated document rather than the old document.
Your code should look something like this:
query = {
email: localStorage.getItem("email"),
restore: 'yes'
}
object = {
findAndModify: '<collection>' // use your own collection name
query: query,
update: {
$set: {
restore: "no"
}
},
new: true
}
$.ajax({
url: "https://api.mongolab.com/api/1/databases/db/runCommand?apiKey=apiKey",
data: JSON.stringify(object),
type: "POST",
contentType: "application/json"
}).done(function(restored_obj) {
console.log(restored_obj)
})
Also, if you ever want to make an update to a single document by _id, the default behavior is that the updated document will be returned. See the documentation for updating single documents here.
Related
I am using AJAX to send a POST request to a Flask route, but I don't know how to get the post data in a format I can read.
My route looks like this:
#app.route("/sendinvites", methods=["POST"])
#login_required
def sendinvites():
print(request.get_data("emails"))
return jsonify("done")
My AJAX looks as:
$.ajax({
type: "POST",
dataType: "json",
url: "/sendinvites",
data: { emails : emails, usernames: usernames },
success: function(data) {
console.log(data)
}
});
An example of the data sent in the emails variable is:
0: Object { id: undefined, username: "me#mydomain.com" }
An example of the output from the route is:
b'emails%5B0%5D%5Busername%5D=me%40mydomain.com'
Does anyone know how I can get the post data into a dictionary object so it is easier to process?
There are many ways to do this, but first, verify that the request contains a valid JSON.
request.get_json()
request.get_json(silent=True)
With silent=True set, the get_json function will fail silently when trying to retrieve the JSON body. By default, this is set to False.
jsonify(request.json)
This will return the entire request object. You'll have to extract the required part by specifying the key posted while sending the request in your ajax code.
Refer this for Flask part, thread
Refer this for Ajax part, thread
I have spend over 10 hours trying to figure this out and looking at similar examples from other people but unfortunately I haven't been able to find out what's my problem here.
I have a ServiceStack Webservice setup:
http://example.com/v1/getuser?code=abcd&lastname=doe&format=json
If I run the above via the browser I will get the following:
[{"nameresult":"joe"}]
I am trying to get this via making an ajax call as follow:
var code = $("#code_field").val();
var lastname = $("#lastname_field").val();
$.ajax({
url: "http://example.com/v1/getuser",
type: "POST",
data: JSON.stringify({
code: code,
lastname: lastname,
format: 'json'
}),
contentType: "application/json; charset=utf-8",
success: function (data) {
var returned_data = data;
alert('returned_data=' + returned_data);
},
error: function (xhRequest, ErrorText, thrownError) {
console.log('xhRequest: ' + xhRequest + "\n");
console.log('ErrorText: ' + ErrorText + "\n");
console.log('thrownError: ' + thrownError + "\n");
}
});
When I run the above, I get the following:
returned_data=[object Object]
Does anyone knows how could I get the json result, nameresult=joe? I am assuming that [object Object] contains [{"nameresult":"joe"}] but I am not entirely sure because I cannot see inside the object :(. thanks so much.
LATEST UPDATE - PROBLEM SOLVED!
I figured out the problem I was having. It had to do with ServiceStack and not with the Ajax call. My problems was the following, I hope it helps someone else one day that may face the same issue.
1.- I needed to enable CORS support on ServiceStack in order to allow posting parameters from Ajax:
File: AppHost.cs
//Permit modern browsers (e.g. Firefox) to allow sending of any REST HTTP Method
base.SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type" },
},
});
Plugins.Add(new CorsFeature());
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
//Handles Request and closes Responses after emitting global HTTP Headers
if (httpReq.HttpMethod == "OPTIONS")
httpRes.EndServiceStackRequest(); //httpExtensions method
// =>after v.3.9.60, => httpRes.EndRequestWithNoContent();
});
2.- My getuser method was in the GET instead of POST. I moved that to the POST and problem solved.
Moved getuser from here: public object Get(...) into here public object Post(...)
Thanks to all for helping me figure this out.
Use console.log to output returned_data by itself:
console.log(returned_data);
This will display the JSON object:
{"nameresult":"joe"}
Your original alert concatenates the string "returned_data=" with the JSON object, and thus the object is converted to a placeholder string "[object Object]" by the browser.
I often put my label in one log, and the object in another:
console.log('returned_data:');
console.log(returned_data);
I've read a couple of posts here regarding how to do this and I can get it working only half-way.
This works (sending json object as text):
function go(itemid)
{
apiRoutes.controllers.Application.addItem(itemid).ajax({
data: '{"reqid":0,"iid":2,"description":"adsf"}',
dataType: 'text',
contentType:'application/json',
success: function(reply) {
alert(reply)
}
});
}
This does not (sending object as json):
function go(itemid)
{
apiRoutes.controllers.Application.addItem(itemid).ajax({
data: {"reqid":0,"iid":2,"description":"adsf"},
dataType: 'text',
contentType:'application/json',
success: function(reply) {
alert(reply)
}
});
}
And what I really want to do is something like this (I've already set up the proper combinators):
function go(itemid)
{
apiRoutes.controllers.Application.addItem(itemid).ajax({
data: #Html(Json.stringify(Json.toJson(item))),
dataType: 'text',
contentType:'application/json',
success: function(reply) {
alert(reply)
}
});
}
My controller looks like this:
def addItem(id: Long) = Action (parse.json) { implicit request =>
Logger.info("add item")
request.body.validate(Item.itemReads).map { item =>
thing.addItem(item)
Ok("Succesfully added item.")
}.recoverTotal{
e => BadRequest("Detected error:"+ JsError.toFlatJson(e))
}
}
In the second case, it never gets to the logging code. Instead it returns a 400 Bad Request immediately (this is likely something triggered in the Action (parse.json) bit I think).
I'd rather send the object as json because when I convert to string and description happens to have an apostrophe in it (') that messes things up. I could probaby escape the apostrophe, but hoping that I'm missing something simple about how to do this with an object rather than a string.
Thanks
As described in the API the dataType param is for setting:
The type of data that you're expecting back from the server.
For sending the json use your second approach (don't send it as a String). Use web browser inspector to validate if correct data were send. AFAIK you shouldn't have problem with Handling the JSON request after receiving valid JSON object
If you are trying to send a non-stringified JSON object in Jquery, $.ajax automatically tries to process it with $.param,
If your data in the ajax call looks like this:
data: {"reqid":0,"iid":2,"description":"adsf"}
This is what $.ajax is doing under the hood before sending:
$.param({"reqid":0,"iid":2,"description":"adsf"})
// "reqid=0&iid=2&description=adsf"
It takes the JSON and serializes it into a form-url-encoded format. Whereas your server is expecting JSON. I would suggest the best way to get around this is to just stringify before sending:
data: JSON.stringify({"reqid":0,"iid":2,"description":"adsf"})
Source: http://api.jquery.com/jQuery.ajax/#sending-data-to-server
From my extended Ext.data.TreeStore:
proxy: {
type: 'ajax',
api: {
read: "/GetTree.json",
update: "/SetTree.aspx?username=user1"
},
reader: {
type: 'json',
root: 'children'
},
listeners: {
exception: function (proxy, response, options) {
// error case
console.log('Exception in Portlets store proxy...');
console.log(response);
}
}
},
What I am trying to figure out is how can I make the username=user1 dynamic, such that I could pass in user2 and have the aspx page process with that user data.
I cannot figure out if/how TreeStore.sync() allows parameters to be passed into it.
Update:
What I am really after here is the ability to save back the entire tree structure as a JSON string instead of just the record that was updated. I can build the JSON string I need to pass but cannot figure out how to actually get that information to my SetTree.aspx page.
You can try setting extra params on the proxy before calling sync:
store.proxy.extraParams = { param1 : '', param2 : '' };
There is anecdotal evidence that suggests this works in 4.1.3 but not earlier versions.
Another thought is to just fire a regular Ajax.request and send desired params along instead of using the tree store to do that.
I know this is old, but for people like me that were searching for the same question...
If you want to save the entire structure instead of just the modified lines, you need to define a writer in your store proxy and in that writer, set writeAllFields: false:
proxy: {
type: 'ajax',
api: {
read: "/GetTree.json",
update: "/SetTree.aspx?username=user1"
},
reader: {
type: 'json',
root: 'children'
},
listeners: {
exception: function (proxy, response, options) {
// error case
console.log('Exception in Portlets store proxy...');
console.log(response);
}
},
writer: {
type: 'json',
writeAllFields: true
}
},
I switched to POST searches using ajax in my application so I can start using the date range. However it seems no matter what I post it keeps returning the first 10 results in my index. The true results are in the 30k range.
amplify.request.define("searchPostRequest", "ajax", {
url: "http://leServer:9200/people/person/_search",
type: "POST",
dataType: 'jsonp',
contentType: 'application/json'
});
self.advancedSearchPostQuery = {
query: {
term: {
locationNumber:479
}
}
};
console.log(self.advancedSearchPostQuery);
amplify.request({
resourceId: "searchPostRequest",
data: JSON.stringify(self.advancedSearchPostQuery),
success: function (data) {
console.log(data.hits.hits.length);
}
});
If this is your actual code, your problem might simply be that your
advancedSearchPostQuery isn't valid JSON.
You need to apply quotes:
advancedSearchPostQuery = {
"query": {
"term": {
"locationNumber": 479
}
}
}
And I'm not sure if you need to stringify the object, but I'm not familiar with amplifyJS, so double check on that as well if amplifyjs is expecting an object or a string.
If that doesn't help check if your query returns the correct results when running from command line through curl.
After doing more debugging I found that the request was being sent as a GET even though I had explicitly set it to post. Moving the data type to json, from jsonp let the request be sent as a POST, which resolved the issue. However this causes an issue in IE where the request is not sent at all due to the request being sent to another domain.
amplify.request.define("searchPostRequest", "ajax", {
url: "http://leServer:9200/people/person/_search",
type: "POST",
dataType: 'json',
contentType: 'application/json'
});