I am getting a 'POST 400 bad request' error when trying to update a table on parse.com using JS SDK.
var Gallery = Parse.Object.extend("Gallery");
var gallery = new Gallery();
var activeArtworks = 0;
gallery.save(null, {
success: function(gallery) {
gallery.set("activeArtworks", activeArtworks);
gallery.save();
}
});
Please help!
I can't see how this is any different to the sample code provided by parse here
The sample code you reference creates all of its parameters before setting up the save() method. This is the step you're missing; you need to create the activeArtworks parameter on your gallery instance. Your update is failing because you're trying to update a property that was never created.
I would expect this code to work, though I didn't test it because parse.com requires you to set up an account to run any code, which is silly, and I didn't feel like creating one:
var Gallery = Parse.Object.extend("Gallery");
var gallery = new Gallery();
var activeArtworks = 0;
gallery.activeArtworks = []; // or some more appropriate default if you have one.
gallery.save(null, {
success: function(gallery) {
gallery.set("activeArtworks", activeArtworks);
gallery.save();
}
});
It might also be worth checking if there's any info in the headers of the 400 error (the debug console in your browser will show these in its Network tab). I would expect Parse to give you some sort of information to help you debug issues, and that's the only place it would fit for an HTTP error.
If you had use user.logIn(callback) function with Parse JS, maybe your session invalid. Please check your callback function error code, if error.code==209 (invalid session token), use Parse.User.logOut() and re-login again.
Like this:
if (error.code == 209) {
Parse.User.logOut();
user.logIn(loginCallback);
return;
}
I had this same issue and it was resolved after realising that the data type that I was posting was different to that specified in the columns that I had created.
In my case, I was trying to save an object when I had specified an array when creating the column in the class.
Related
I am using Apollo Client to make an application to query my server using Graphql. I have a python server on which I execute my graphql queries which fetches data from the database and then returns it back to the client.
I have created a custom NetworkInterface for the client that helps me to make make customized server request (by default ApolloClient makes a POST call to the URL we specify). The network interface only has to have a query() method wherein we return the promise for the result of form Promise<ExecutionResult>.
I am able to make the server call and fetch the requested data but still getting the following error.
Error: Network error: Error writing result to store for query
{
query something{
row{
data
}
}
}
Cannot read property 'row' of undefined
at new ApolloError (ApolloError.js:32)
at ObservableQuery.currentResult (ObservableQuery.js:76)
at GraphQL.dataForChild (react-apollo.browser.umd.js:410)
at GraphQL.render (react-apollo.browser.umd.js:448)
at ReactCompositeComponent.js:796
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:746)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:724)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:645)
at ReactCompositeComponentWrapper.performUpdateIfNecessary (ReactCompositeComponent.js:561)
at Object.performUpdateIfNecessary (ReactReconciler.js:157)
at runBatchedUpdates (ReactUpdates.js:150)
at ReactReconcileTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
at Object.flushBatchedUpdates (ReactUpdates.js:172)
at ReactDefaultBatchingStrategyTransaction.closeAll (Transaction.js:206)
at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:153)
at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
at Object.enqueueUpdate (ReactUpdates.js:200)
I want to know the possible cause of the error and solution if possible.
I had a similar error.
I worked it out by adding id to query.
for example, my current query was
query {
service:me {
productServices {
id
title
}
}
}
my new query was
query {
service:me {
id // <-------
productServices {
id
title
}
}
}
we need to include id,
otherwise it will cause the mentioned error.
{
query something {
id
row {
id
data
}
}
}
I've finally found out what is causing this issue after battling with it in various parts of our app for months. What helped to shed some light on it was switching from apollo-cache-inmemory to apollo-cache-hermes.
I experimented with Hermes hoping to mitigate this ussue, but unfortunately it fails to update the cache the same as apollo-cache-inmemory. What is curious though is that hermes shows a very nice user friendly message, unlike apollo-cache-inmemory. This lead me to a revelation that cache really hits this problem when it's trying to store an object type that is already in the cache with an ID, but the new object type is lacking it. So apollo-cache-inmemory should work fine if you are meticulously consistent when querying your fields. If you omit id field everywhere for a certain object type it will happily work. If you use id field everywhere it will work correctly. Once you mix queries with and without id that's when cache blows up with this horrible error message.
This is not a bug-it's working as intended, it's even documented here: https://www.apollographql.com/docs/react/caching/cache-configuration/#default-identifiers
2020 update: Apollo has since removed this "feature" from the cache, so this error should not be thrown anymore in apollo-client 3 and newer.
I had a similar looking issue.
Perhaps your app was attempting to write (the network response data) to the store with the wrong store address?
Solution for my problem
I was updating the store after adding a player to a team:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id } };
const data = store.readQuery(addr);
stored.teams.players.push(response.data.player));
store.writeQuery({...addr, data});
}
I started to get a similar error above (I'm on Apollo 2.0.2)
After digging into the store, I realised my QUERY_TEAM request made with one variable meta defaulting to null. The store "address" seems to use the *stringified addr to identify the record. So I changed my above code to mimic include the null:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id, meta: null } };
const data = store.readQuery(addr);
data.teams.players.push(response.data.player));
store.writeQuery({...addr, data});
}
And this fixed my issue.
* Defaulting to undefined instead of null will probably avoid this nasty bug (unverified)
Further info
My issue may be only tangentially related, so if that doesn't help I have two peices of advice:
First, add these 3 lines to node_modules/apollo-cache-inmemory/lib/writeToStore.js to alert you when the "record" is empty.
And then investigate _a to understand what is going wrong.
exports.writeResultToStore = writeResultToStore;
function writeSelectionSetToStore(_a) {
var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context;
var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap;
+if (typeof result === 'undefined') {
+ debugger;
+}
Second, ensure all queries, mutations and manual store updates are saving with the variables you expect
For me adding "__typename" into query helped.
Solution for this is 1. it happening when missing id, second one is it is happening when you have same query and hitting them alternately.
Example if you have query like dog and cat.
query dog(){id, name}
query cat(){id, name }
here both query are same just their header are different, during that time, this type of issue is coming. currently i have fetching same query with different status and getting this error and am lost in search of solution.
Scenario = I am slowly but surely wrapping my head around what is going on with Parse's cloud code features. I just need some help from those who would like to answer some short, relatively simple questions about what is going on in some sample cloud code functions.
The code I will use in this example is below
1) cloud code
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId,
newColText = request.params.newColText;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.set('new_col', newColText);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
2) called from iOS
[PFCloud callFunction:#"editUser" withParameters:#{
#"userId": #"someuseridhere",
#"newColText": #"new text!"
}];
This code was taken from here
Question 1 =
(request, response)
I am confused by what this is. Is this like typecasting in iOS where I am saying (in the iOS call) I want to pass an NSString into this function ("userId") and inside the cloud code function I'm going to call it "request"? Is that what's going on here?
Question 2 =
Parse.Object.extend('_User')
Is this grabbing the "User" class from the Parse database so that a "PFObject" of sorts can update it by creating a new "user" in the line below it?
Is this like a...
PFObject *userObject = [PFObject objectWithClassName:#"User"]?
Question 3 =
user.set('new_col', newColText)
This obviously 'sets' the values to be saved to the PFUser (~I think). I know that the "newColText" variable is the text that is to be set - but what is 'new_col'? Only thing I can think of is that this sets the name of a new column in the database of whatever type is being passed through the "request"?
Is this like a...
[[PFUser currentUser] setObject: forKey:]
Question 4 =
Parse.Cloud.useMasterKey()
Without getting too technical, is this basically all I have to type before I can edit a "User" object from another User?
Question 5 =
user.save().then(function(user) {
response.success(user);
}
Is this like a...
[user saveInBackgroundWithBlock:]?
and if so, is
function(error) {
response.error(error)
just setting what happens if there is an error in the saveInBackgroundWithBlock?
Please keep in mind, I know iOS - not JavaScript. So try to be as descriptive as possible to someone who understands the Apple realm.
Here's my take on your questions:
The request parameter is for you to access everything that is part of the request/call to your cloud function, it includes the parameters passed (request.params), the User that is authenticated on the client (request.user) and some other things you can learn about in the documentation. The response is for you to send information back to the calling code, you generally call response.success() or response.error() with an optional string/object/etc that gets included in the response, again documentation here.
That's a way of creating an instance of a User, which because it is a special internal class is named _User instead, same with _Role and _Installation. It is creating an instance of the user with an ID, not creating a new one (which wouldn't have an ID until saved). When you create an object this way you can "patch" it by just changing the properties you want updated.
Again, look at the documentation or an example, the first parameter is the column name (it will be created if it doesn't exist), the second value is what you want that column set to.
You have to do Parse.Cloud.useMasterKey() when you need to do something that the user logged into the client doesn't have permission to do. It means "ignore all security, I know what I'm doing".
You're seeing a promise chain, each step in the chain allows you to pass in a "success" handler and an optional "error" handler. There is some great documentation. It is super handy when you want to do a couple of things in order, e.g.
Sample code:
var post = new Parse.Object('Post');
var comment = new Parse.Object('Comment');
// assume we set a bunch of properties on the post and comment here
post.save().then(function() {
// we know the post is saved, so now we can reference it from our comment
comment.set('post', post);
// return the comment save promise, so we can keep chaining
return comment.save();
}).then(function() {
// success!
response.success();
}, function(error) {
// uh oh!
// this catches errors anywhere in the chain
response.error(error);
});
I'm pretty much at the same place as you are, but here are my thoughts:
No, these are the parameters received by the function. When something calls the editUser cloud function, you'll have those two objects to use: request & response. The request is basically what the iOS device sent to the server, and response is what the server will send to the iOS device.
Not quite that. It's like creating a subclass of _User.
Think of Parse objects types as a database table and it's instances as rows. The set will set (derp) the value of 'newColText' to the attribute/column 'new_col'.
Not sure, never used that function as I don't handle User objects. But might be that.
Pretty much that. But it's more sort of like (pseudo-code, mixing JS with Obj-C):
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
if(error){
response.error(error); // mark the function as failed and return the error object to the iOS device
}
else{
response.success(user); // mark the function call as successful and return the user object to the iOS device
}
}];
I am not using the Javascript SDK because that is client-side whereas I'm making a server-side call.
I want to make a page post so that I can make an ad creative with it. I can do the call perfectly fine in the Graph API Explorer tool, but I cannot make the same call (with the same long-lived access tokens that continue to work in the Graph Explorer) from Javascript. Here is my code:
tok = <valid and never expiring user token>;
var pg_tok = <valid and never expiring page token>;
var act_id = <account_id>;
var pg_id = <page_id>;
var call_to_action = 'INSTALL_MOBILE_APP';
var fb_app_url = 'https://itunes.apple.com/us/app/id284882215';
var msg = 'Test creative, ya see';
var pic_url = 'https://s3.amazonaws.com/<path_to_my_image>';
var ROOT = 'https://graph.facebook.com/';
var pagepost_endpoint = ROOT+pg_id+'/feed';
console.log(pagepost_endpoint);
var pagepost_params = {
access_token: pg_tok,
call_to_action: {
type: call_to_action,
value: {link: fb_app_url}
},
message: msg,
picture: pic_url,
published: false
};
console.log(pagepost_params);
var pagepost_res = HTTP.post(pagepost_endpoint, {params: pagepost_params});
console.log(pagepost_res);
I have played around a bunch with params vs. data for where pagepost_params goes in the HTTP.post that is giving the error (that is Meteor's HTTP btw).
-Putting everything in params gives the error: {"error":{"type":"Exception","message":"No Call To Action Type was parseable. Please refer to the call to action api documentation","code":1373054,"is_transient":false}}.
-Putting everything in data gives the error: {"error":{"message":"(#200) This API call requires a valid app_id.","type":"OAuthException","code":200}}.
-Putting access_token in params and everything else in data gives the error: {"error":{"message":"Invalid parameter","type":"FacebookApiException","code":100,"error_subcode":1349125}}.
One more clue for everyone, if I change the HTTP.post to HTTP.get, and just put access_token in params and include no other parameters (in params or in data), the call succeeds and I see past posts I have made on this page through the Graph Explorer (only the ones with published: true, though), so the access token and endpoint do work, just something is faulty about POST-ing instead of GET-ing and the specific parameters I'm using.
Have you tried posting to /photos instead of /feed? The error subcode is the same as mentioned here Posting to facebook wall using graph api
Hope this helps
Turned out to be an issue with Meteor's HTTP. It does not handle nested JSON very well, and we're going to submit a pull request for that. But for those seeing this, the important thing to take away is that the call_to_action may not be a valid JSON object, and even if it is, it may not be being stringified/parsed as expected. My fix was using request.post instead of HTTP.post. (then instead of params or data, you use form. look up node's request https://github.com/mikeal/request)
I have been trying to automate Lotus Notes mail fillup from a browser interface.
After refering to Richard Schwartz's answer, i came up with this piece of code using the Lotus.NotesSession class.
function SendScriptMail() {
var mToMail = document.getElementById('txtMailId').value
var mSub = document.getElementById('txtSubject').value
var mMsg = document.getElementById('txtContent').value
var Password = "yyy"
alert("1");
var MailFileServer = "xxx.com"
var MailFile = "C:\Program Files\IBM\Lotus\Notes\mail\user.nsf"
alert("2")
var Session;
var Maildb;
var UI;
var NewMail;
var From = "user#xxx.com"
try {
alert("3")
// Create the Activex object for NotesSession
Session = new ActiveXObject("Lotus.NotesSession");
alert("4")
if (Session == null) {
throw ("NoSession");
} else {
Session.Initialize(Password);
// Get mail database
Maildb = Session.GetDatabase(MailFileServer, MailFile);
alert("5")
if (Maildb == null) {
throw ("NoMaildb");
} else {
NewMail = MailDB.CreateDocument();
if (MailDoc == null) {
throw ('NoMailDoc');
} else {
// Populate the fields
NewMail.AppendItemValue("Form", "Memo")
NewMail.AppendItemValue("SendTo", mToMail)
NewMail.AppendItemValue("From", From)
NewMail.AppendItemValue("Subject", mSub)
NewMail.AppendItemValue("Body", mMsg)
NewMail.Save(True, False)
NewMail.Send(False)
}
}
}
} catch (err) {
// feel free to improve error handling...
alert('Error while sending mail');
}
}
But now, alerts 1,2,3 are being trigerrd, and then the counter moves to the catch block. The lotus notes session is not being started.
In a powershell script that I was previously looking at there was a code regsvr32 "$NotesInstallDir\nlsxbe.dll" /s that was used before the Session = new ActiveXObject("Lotus.NotesSession");. Is there something similar in javascript too, if so how do i invoke that dll.
I think I've realised where I am going wrong. According to me, upto alert("5") things are good. But since Lotus.NotesSession doesn't have a CreateDocument() method, it is throwing the error. I am not sure how to create the document and populate the values though.
Since you've chosen to use the Notes.NotesUIWorkspace class, you are working with the Notes client front-end. It's running, and your users see what's happening on the screen. Are you aware that there's a set of back-end classes (rooted in Lotus.NotesSession) instead of Notes.NotesSession and Notes.NotesUIWorkspace) that work directly with Notes database data, without causing the Notes client to grab focus and display everything that you're doing?
Working with the front-end means that in some cases (depending on the version of Notes that you are working with) you're not going to be working directly with the field names that are standard in Notes messages as stored and as seen in the back-end. You're going to be working with names used as temporary inputs in the form that is used to view and edit the message. You can see these names by using Domino Designer to view the Memo form.
Instead of using 'SendTo', try using:
MailDoc.Fieldsettext('EnterSendTo', mToMail)
Regarding the Body field, there's no temporary field involved, however you haven't really explained the difficulty you are having. Do you not know how to display the interface that you want in the browser? Do you not know how to combine different inputs into a single FieldSetText call? Or are you just dissatisfied with the fact that FieldSetText can't do any fancy formatting? In the latter case, to get more formatting capability you may want to switch to using the back-end classes, which give you access to the NotesRichTextItem class, which has more formatting capabilities.
I'm working on a broadcast e-mail template that would pull the latest three articles off our blog from an RSS feed and insert the relevant sections into the document.
I looked at the documentation, and based on the bit about the File object, some of my own debugging, and an InDesign forum post I've learned that it's not possible to use the File object to source an online XML file.
The alternative (without resorting to an external script, one of which didn't work for me anyways), it seems, is to use the Socket object. So I went back to the documentation and copied/pasted this code verbatim from there:
reply = "";
conn = new Socket;
// access Adobe’s home page
if (conn.open ("www.adobe.com:80")) {
// send a HTTP GET request
conn.write ("GET /index.html HTTP/1.0\n\n");
// and read the server’s reply
reply = conn.read(999999);
conn.close();
}
When I ran it, I received this descriptive error message:
A search for "89858 javascript error" yielded nothing useful.
So I'm stuck. Either Adobe's code sample has an error, or, more likely, there's something wrong on my end. If I had to guess, I'd guess that it's some kind of proxy problem, but I don't know for sure and don't know how to find out.
Can anyone help? The principles of the Socket object make sense to me, but if I can't get even the sample to work, I don't really have anywhere to go with this.
The error above occurs when you return certain objects (XML, Socket) from a function call, but the return values does not get assigned anywhere.
function test() {
var xml = new XML('<test />');
return xml;
}
test();
The above will cause an error. To get around it you have to assign the return value somewhere.
var result = test();
Try to put all collect all function calls result. I am not sure which one causes the error.
var reply = "";
var conn = new Socket;
// access Adobe’s home page
if (conn.open ("www.adobe.com:80")) {
// send a HTTP GET request
var result = conn.write ("GET /index.html HTTP/1.0\n\n");
// and read the server’s reply
reply = conn.read(999999);
var close = conn.close();
}