Inserting Data to Wix via JSON/REST API: WD_PERMISSION_DENIED - permissions

I'm trying to insert data to my Wix collection using the API. I'm using a POST function and am posting a JSON document. It's supposed to simply add a new row to a database containing 1 value.
Here is the http-functions.js which I can trigger without issues (it's more or less a copy of the example from the documentation):
import {created, serverError} from 'wix-http-functions';
import wixData from 'wix-data';
export function post_peopleCount(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
};
// get the request body
return request.body.text()
.then( (body) => {
// insert the item in a collection
return wixData.insert("NumberOfPeopleDB", JSON.parse(body));
} )
.then( (results) => {
options.body = {
"inserted": results
};
return created(options);
} )
// something went wrong
.catch( (error) => {
options.body = {
"error": error
};
return serverError(options);
} );
}
The database looks like this:
and the JSON I am posting looks like this:
But the Error I am getting is:
But the permissions I have set for the collection is:
Do you know why I might be getting that "WD_PERMISSION_DENIED" and 500 Server Error? (The data does not get entered.)
Thanks!

My friend, its not related to creating a collection from scratch it is because of the permissions set to this collection once created. You fixed that by not noticing :).
Permission need to be given in order to perform such queries.

It turns out, if I create a new collection (= table) from scratch, it works. I also changed the field value in the collection to people, maybe value is a reserved term. Nevertheless, now it seems to work:
So if you run into the same problem: Try recreating the collections from scratch.

The critical thing for me which has not been mentioned yet is that you need to set the collection to have form-like permissions so that anyone has permission to submit data to the collection.

Related

Storing results of SQL Select query in a var node js

I'm looking for a way to store the results of this select query like a "rank" chart for a game but I'm not sure if what I'm encountering is an async issue or a data-type issue or something else entirely. Any thoughts?
var ranksVar = [];
db.all("select * from user", function(err, rows){
if(err) {
throw err;
} else {
setValue(rows);
}
});
function setValue(value) {
ranksVar = value;
console.log(ranksVar);
}
I've found out a useful post about using SQLite with NodeJS and it gives you the basic examples needed to understand how to use it. Here it is: SQLite NodeJS
In your case, look under the section data query.
Here the example code:
const sqlite3 = require('sqlite3').verbose();
// open the database
let db = new sqlite3.Database('./db/chinook.db');
let sql = `SELECT DISTINCT Name name FROM playlists
ORDER BY name`;
db.all(sql, [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.name);
});
});
// close the database connection
db.close();
As you can see, the rows variable is (I guess) a special type created by the module. To get all data from it, you might want to iterate over it and push it into your array variable.
Cheers 😁 !
I figured out the issue. It was a data type/async issue, I was trying to print a string for an undefined array.
Went back a loop and used the JSON.stringify method to display the array objects correctly.

Create - How to handle empty response

My API doesn't return any response in body on POST,PATCH, etc for some resources.
How are we supposed to handle this case in data provider ?
I tried to return an empty data object but unfortunately I get the error :
"The response to 'CREATE' must be like { data: ... }, but the received response does not have a 'data' key. The dataProvider is probably wrong for 'CREATE'."
I don't know how your dataProvider looks like or what the response of your API for POST/PUT requests is, but the problem is probably located in your dataProvider's convertHTTPResponseToREST as this is responsible for handling your API's responses.
Try the following:
case CREATE:
return { data: { ...params.data, id: json.id } };
If this doesn't work either, then try this one:
case CREATE:
return { data: json };

Cloud Function retrieving a value based on URL parameter

I am trying to write a Cloud Function in node where I can return a token from a parameter.
The URL I use is...
https://us-central1-nmnm03.cloudfunctions.net/GetAccount?taccount=Asd
my function is this... and its wrong. I suspect I am not assigning TT properly.
var functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.GetAccount = functions.https.onRequest((req, res) => {
const t = admin.database().ref('/newaccout/'+req.query.account)
const tt = t.child(token)
res.send( "res is " + tt );
});
req.query.account is the Key. One of the Items in the document is token
ideally, I would like to get something like...
{"token":"23453458885"}
Could I get a node hint please... thanks
Though, I am not a firebase geek. What it seems from the documentation is that you will have two events that you can use to listen for retrieving child data. You can read further more here. The given options are used for different cases. Please follow through the mentioned link to have clear view.
Inside your cloud function you can try doing following:
const t = admin.database().ref('/newaccout/'+req.query.account)
t.on('child_added', function(data) {
res.json({
token: data.token
})
})
Or maybe like this:
const t = admin.database().ref('/newaccout/'+req.query.account)
t.once('value', function(snapshot) {
//Process it like above
//But here you will get al child elements at once
});
It looks like you are expecting to query the value found at a database reference stored at t. Unfortunately, you haven't actually performed a query yet. tt is just yet another Reference object that points to a location in the database. You should use the once() method on Reference to query a database location. Also bear in mind that you are using a variable called token, but you haven't defined yet in your code. To me, that looks like it would generate an error to me.
You might be well served by looking at a bunch of the sample code.

vue.js - Cannot read property 'toLowerCase' of undefined

I am filtering projects with a computed property like this:
filtered_projects() {
return this.projects.filter( (project) => {
return project.title.toLowerCase().indexOf(this.project_filter.toLowerCase()) !== -1
})
}
When I add a new project using this
submitNewProject() {
let path = '/api/projects';
Vue.http.post(path, this.project)
.then( (rsp) => {
this.projects.push(rsp.data);
this.project = this.getSingleProject();
this.create_project = false;
return true;
});
}
This is giving me an error that I can't find
TypeError: Cannot read property 'toLowerCase' of undefined
It may just be that you are not correctly passing the projects data to the projects array.
Firstly vue-resource now uses body not data to get the response, therefore you may need to use:
this.projects.push(rsp.body)
then this will give you a single array item containing all projects which doesn't look like what you want. I believe instead you're after:
this.projects = rsp.body
Assuming the response body is an array of objects this will then allow:
this.projects.filter(project => {})
to work as expected. Meaning project.title should now be valid
EDIT
For a project title to be set to lowerCase you must be returning an object with a title param, i.e.
rsp.body = {
title: 'FOO',
}
which you'd then set on the projects array via:
this.projects.push(rsp.body)
so the first thing to fix is your response, sort your endpoint so it returns what you are expecting, then the rest of the above code should work
You need preserve "this" before Vue.http.post (self=this) and then in callback change this.projects to self.projects.
Explanation:
How to access the correct `this` context inside a callback?

Validate Form on Change ONLY

Because much of our imported data technically has validation errors, users are unable to update fields without first correcting previously entered bad data. This wouldn't be a problem except that many times this user doesn't have the information needed to enter a correct value into that field but we still need to save their update.
Is it possible to disable the validate on submit for a DynamicForm?
Is it possible to disable the validate on submit for a DynamicForm?
there's a disableValidation attribute, it disables client-side validators.
The best solution I could find thus far.
I'm disabling validation and overridding getValues, which is called as part of saveData so I manually parse through any fields and look for errors. If I find an error I remove it from the return value and store it under the valuesManager.invalidatedFields.
If a field had an error it will not be included in the save, but because the server will return the original value I had to override setValues as well to prevent your (bad) change from being overridden.
Also, because getValues is called on initial load it validates on load as well.
isc.ValuesManager.create({
disableValidation: true,
invalidatedFields: {},
setValues: function(values){
console.log("setting values..", this.invalidatedFields);
for (var key in this.invalidatedFields) {
if (this.invalidatedFields.hasOwnProperty(key)) {
values[key] = this.invalidatedFields[key];
}
}
this.Super("setValues", arguments);
},
getValues: function () {
this.invalidatedFields = [];
var data = this.Super("getValues");
for (var key in data) {
if (data.hasOwnProperty(key)) {
var form = this.getMemberForField(key);
if (form && !form.getField(key).validate()) {
console.log(key + " failed validation", data[key]);
this.invalidatedFields[key] = data[key];
delete data[key];
}
}
}
return data;
}
});