I am trying to get all columns from a class in a Parse platform using cloud code that returns a list/array of all the names of the columns.
I am looking at the schema section of the documentation, but I can't find how to get the column's names, only adding, deleting, ...
However, I found this method, but I haven't figured out how to use it neither found any example.
This is what I have right now (doesn't work, neither is the only thing I tried, but hopefully it can help you understand my situation):
Parse.Cloud.define("getAllProperties", async (request) => {
var mySchema;
try {
mySchema = new Parse.Schema('Entry');
} catch (error) {
console.error("ERROR " + error.code + ': ' + error.message);
return error;
}
console.log("CloudFunction 'getAllProperties' executed successfully.");
return mySchema.toString();
});
I found a way to do it:
Parse.Cloud.define("getAllProperties", async (request) => {
var mySchema;
try {
mySchema = new Parse.Schema('Entry');
mySchema = await mySchema.get()
} catch (error) {
console.error("ERROR " + error.code + ': ' + error.message);
return error;
}
console.log("CloudFunction 'getAllProperties' executed successfully.");
return JSON.stringify(mySchema);
});
Related
I have a cloud function that uses firebase and after I call it from my angular app I get the mentioned above error:
Unhandled error RangeError: Maximum call stack size exceeded
at baseKeys (/workspace/node_modules/lodash/lodash.js:3483:12)
at keys (/workspace/node_modules/lodash/lodash.js:13333:60)
at /workspace/node_modules/lodash/lodash.js:4920:21
at baseForOwn (/workspace/node_modules/lodash/lodash.js:2990:24)
at Function.mapValues (/workspace/node_modules/lodash/lodash.js:13426:7)
at encode (/workspace/node_modules/firebase-functions/lib/providers/https.js:184:18)
at /workspace/node_modules/lodash/lodash.js:13427:38
at /workspace/node_modules/lodash/lodash.js:4925:15
at baseForOwn (/workspace/node_modules/lodash/lodash.js:2990:24)
at Function.mapValues (/workspace/node_modules/lodash/lodash.js:13426:7
I've searched stack to find solutions - but in most cases there was serialization problem, that I believe DOES NOT happen here.
Here is my function:
exports.createCase = functions.region('europe-west2').https.onCall((data, context) => {
console.log("creating new case");
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'This function must be called ' +
'while authenticated.');
}
const caseName = data.caseName;
// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;
console.log("caseName=" + caseName + " uid=" + uid + " name=" + name + " picture=" +
picture + " email=" + email);
var operationResult = new Promise ((resolve, reject) => {
var accessData : any = {};
var accessId = admin.database().ref('/access/').push();
var operationId = admin.database().ref('/operationslog/' + accessId.key + '/').push();
console.log("accessId created=" + accessId + ' || ' + accessId.key + ' operations id=' +
operationId + ' || ' + operationId.key);
let now: number = Date.now();
accessData[`/access/` + accessId.key] = new Access(caseName, uid, email);
accessData[`/operationslog/` + accessId.key + `/` + operationId.key] = {
date: now,
performedByUser: uid,
performedByMail: email,
performedByImg: picture,
performedBySystem: false,
operationType: 'CREATE',
order: (REVERSE_ORDER_MAX - now),
details: {creator: uid, name: caseName}
};
console.log('commiting data');
admin.database().ref().update(accessData).then( (value: void) => {
console.log("returning ok result");
resolve({
status: "Ok",
accessId: accessId,
description: 'Case created'
});
}, err => {
console.log("Error while trying to create case: " + err);
reject("CASE NOT CREATED");
}
).catch(exception => {
console.log("Error while trying to create case: " + exception);
reject("CASE NOT CREATED");
}
);
}
);
return operationResult;
});
and the call from Angular app:
let createCaseCall = functions.httpsCallable('createCase');
createCaseCall({caseName: value.caseName}).then(result => {
// Read result of the Cloud Function.
console.log("got result: " + result);
if (result.data.status == 'Ok') {
this.showSuccessMessage('Case created.');
}
}).catch(err => {
console.log("Error while calling cloud functions: " + err);
this.showErrorMessage('Error while creating the case.');
});
Now, the important information is that, the data in firebase realtime database IS CREATED when this function is called and console log does contain "returning ok result" line...
It is still a serialization problem.
Here's what you're trying to send back to the client:
resolve({
status: "Ok",
accessId: accessId,
description: 'Case created'
});
accessId is the result of a push operation:
var accessId = admin.database().ref('/access/').push();
That means it's a DatabaseReference object, which contains circular references that can't be serialized. It's not a simple data type, like a string.
You'll want to think more carefully about what you want exactly you want to send back to the client app. Maybe you wanted to send back the name or path of the child key that was created by push()?
Also, you'll probably want to remove the whole new Promise() thing, as that's an anti-pattern here. There is no need to create a new promise when you have promises from all the other database operations available to work with.
Im making a Node-js app which needs to look up some info from the database before proceeding with another db-call, but I cant seem to make sure that the first check is resolved before proceeding. How can I make sure that the first query is always fulfilled before proceeding? I've tried nesting .next, but they seem to be skipping anyway. So after the first DB-call I want to check the returned value, but its always undefined.
my async function:
async function GetStuff(text, id){
try {
return await db.query(text, id);
} catch(error) {
console.log('fel inne: ' + error)
logger.error('Fel: ' + error)
return null;
}
}
My Controller-code where I call the method and then try await the call with .next.
router.post('/newStuff', async (req, res) => {
//Check if number exist in DB
const checkUserText = 'select * from public.User WHERE Mobilenumber = $1 limit 1';
const values = [req.body.from];
GetStuff(checkUserText, values)
.then(function(result) {
var user = result.rows[0];
//HERE I GET UNDEFINED for some reason. I need to check the result in order to select the next step.
if(user.userid !== null){
console.log(user)
//do some stuff...
}
else {
res.end('Not OK')
}
}).catch(function(error) {
console.log('fel: ' + error)
logger.error('Fel: ' + error)
res.end('Error')
});
})
Instead of returning null from GetStuff, you should probably throw either the original error or a new error. This will then cause GetStuff.catch to be triggered if something goes wrong with the database call.
Just a tip as well, your controller function is async so you don't need to use Promise based structure in your controller code. You can also use async/await.
With both of those, you'd end up with the following code:
async function GetStuff(text, id){
try {
return await db.query(text, id);
} catch(error) {
console.log('fel inne: ' + error)
logger.error('Fel: ' + error)
throw new Error('Failed to get db record');
}
}
router.post('/newStuff', async (req, res) => {
//Check if number exist in DB
const checkUserText = 'select * from public.User WHERE Mobilenumber = $1 limit 1';
const values = [req.body.from];
let dbResult;
try {
dbResult = await GetStuff(checkUserText, values);
} catch (err) {
console.log('fel: ' + error)
logger.error('Fel: ' + error)
res.sendStatus(500);
}
const user = dbResult.rows[0];
if (user.userid !== null) {
console.log(user);
}
// Do some more things...
res.sendStatus(200); // All good!
}
I want to set up my custom code in cloud code of parse.
Parse.Cloud.job("deleteUser", function(request, status) {
const query = new Parse.Query("SegmentData");
query.equalTo("userID", request.userID);
query.find()
.then(Parse.Object.destroyAll)
.catch(function(error) {
console.error("Error finding related comments " + error.code + ": " + error.message);
});
const query2 = new Parse.Query("ShowData");
query.equalTo("userID", request.userID);
query.find()
.then(Parse.Object.destroyAll)
.catch(function(error) {
console.error("Error finding related comments " + error.code + ": " + error.message);
});
});
This is the code I have written so far. I want to destroy all the users that have username. They can be even more than 1000. Will this work if the users have more than 1000 records or do I have to amend my code?
With the parse-server the limit of each query is 100 you need to set to
query.limit(1000);
If you want to have 1000 users maximum
You can see here how parse-server test and set the limit of each query:
https://github.com/parse-community/parse-server/blob/master/spec/ParseAPI.spec.js#L314
https://github.com/parse-community/parse-server/blob/master/src/Routers/ClassesRouter.js#L29
Select statements are working fine, but whenever I try an insert or update the recordset and affected values are undefined. The insert/update works in the DB, I just can't read the returned values.
var sql = require('mssql');
var config = {...};
sql.connect(config).then(function() {
new sql.Request().query("INSERT INTO MyTable (Name, Age) VALUES ('John', 30)").then(function(recordset, affected) {
console.log('Recordset: ' + recordset);
console.log('Affected: ' + affected);
}).catch(function(err) {
console.log('Request error: ' + err);
});
}).catch(function(err) {
if (err) {
console.log('SQL Connection Error: ' + err);
}
});
The output to console is:
Recordset: undefined
Affected: undefined
I feel like I must be missing something really simple here.
As mentioned in the comments, INSERT statement doesn't return a recordset so recordset is undefined. Please see this section of the docs to learn more about how to get number of affected rows.
The problem with your code is you're expecting affected as a second argument from the promise, but promises does only support one argument. Because of that you must access number of affected rows this way:
var sql = require('mssql');
var config = {...};
sql.connect(config).then(function() {
var request = new sql.Request();
request.query("INSERT INTO MyTable (Name, Age) VALUES ('John', 30)").then(function(recordset) {
console.log('Recordset: ' + recordset);
console.log('Affected: ' + request.rowsAffected);
}).catch(function(err) {
console.log('Request error: ' + err);
});
}).catch(function(err) {
if (err) {
console.log('SQL Connection Error: ' + err);
}
});
If you want id to be output parameter
const sql = require("mssql/msnodesqlv8");
const pool = new sql.ConnectionPool(dbConfig);`
const poolConnect = pool.connect();
let query = `INSERT INTO <table>(fields) VALUES(values);SELECT #id = SCOPE_IDENTITY()`
await poolConnect;
pool.request()
.output("id", sql.Int)
.query(query).then((err, result) => {
console.log(result.output.id)
}).catch(err => {
console.log(err)
})`
In order to make this question as useful to as many people as possible, I will exclude my specific implementation details beyond that fact that I am using the Bluebird promise library with Node + Express below.
So, let's say that I have the following chain (where P returns a promise, and res is the Express HTTP response object):
P().then(function(){
// do nothing if all went well (for now)
// we only care if there is an error
}).catch(function(error){
res.status(500).send("An error occurred");
}).then(function(){
return P();
}).then(function(pVal1){
return [pVal1, P()];
}) // TODO: catch an error from P() here and log pVal1
.spread(function(pVal1, pVal2){
if(pVal1 === pVal2) {
console.log("Success!");
} else {
console.log("Failure");
}
});
Where I have placed the TODO comment above is where I would like to catch an error that might occur from my call to P. If I do catch an error, I would like to log pVal1 and then send a 500 error, as is done in the first catch. However, I am not sure if this is possible with how I am structuring my chain.
I believe that I need to do some "branching," but I do not think that I understand this concept well enough to stop the asynchronous nature of JavaScript from getting the best of me! As such, any help is thoroughly appreciated.
Don't forget to catch errors in the end of the chain. That's also the place to send the response.
Catching errors in the middle of a chain is for intermittent error handling; the chain continues to run, so don't send a response just yet.
Here is something to try it out:
// example middleware
function handle(req, res, next) {
log("----------------");
return async("p1", "foo").then(function (pVal1) {
return pVal1;
}).then(function (pVal1) {
var p2a = async("p2a", "bar"),
p2b = async("p2a", "bar").catch(function (error) {
log("Logging: " + error + " (pVal1 " + pVal1 + ")");
});
return [p2a, p2b];
}).spread(function (pVal1, pVal2) {
if (pVal1 === pVal2) {
res.send("Success!");
} else {
res.send("Failure");
}
}).catch(function (error) {
res.status(500).send("An error occurred");
log("Logging: " + error);
});
}
// ---------------------------------------------------------------------
// mockup response object
var res = {
status: function (code) {
log("Sending status: " + code);
return this;
},
send: function () {
log("Sending response: " + [].join.call(arguments, " "));
return this;
}
};
// mockup promise generator
function async(name, value) {
return new P(function (resolve, reject) {
if ( confirm("let " + name + " succeed?") ) {
log(name + " succeeds...");
resolve(value);
} else {
log(name + " fails...");
reject(name + " has failed");
}
});
}
function log() {
var msg = document.createElement("DIV");
msg.textContent = [].join.call(arguments, " ");
document.getElementById("log").appendChild(msg)
document.body.scrollTop = document.body.scrollHeight;
}
button {
position: fixed;
top: 5px;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>
<button onclick="handle(null, res, null)">Go</button>
<div id="log"></div>
This is possible if you use the explicit Promise.all instead of returning an array into .spread.
}).then(function(pVal1){
// this becomes a `Promise.all` - the aggregation is explicit
var all = Promise.all([pVal1, P()]);
all.catch(function(e){ // "branching", we both return and `catch` the promise
console.log("Error, pVal1 is", pVal1);
});
return all; // return it
}).spread(function(pVal1, pVal2){
// ....
});