unable to parse users query results using titanium cloud - javascript

I am performing a query on users(titanium cloud service) as such:
Cloud.Users.query({
page: 1,
per_page: 5,
where: {
email: 'example#example.com'
}
}, function(e) {
if (e.success) {
alert(JSON.parse(e.users));
} else if (e.error) {
alert(e.message);
} else {}
});
After executing the query I am unable to parse e.users on success, alert returns nothing. Any thoughts?

From what I understand from this example in Titanium docs, e.users is an array, not a JSON string. You should be able to do something like:
for (var i = 0; i < e.users.length; i++) {
var user = e.users[i];
alert('id: ' + user.id + '\n' +
'first name: ' + user.first_name + '\n' +
'last name: ' + user.last_name);
}

You're trying to parse e.users which is an array. You should traverse through the array using a loop and you can simply alert each user using JSON.stringify method
Try the following code
Cloud.Users.query({
page: 1,
per_page: 5,
where: {
email: 'example#example.com'
}
}, function (e) {
if (e.success) {
alert('Total Users: ' + e.users.length);
for (var i = 0; i < e.users.length; i++) {
var user = e.users[i];
alert(JSON.stringify(user)); //This line will display the details of the user as a string
}
} else {
alert('Error:\n' +
((e.error && e.message) || JSON.stringify(e)));
}
});
You should read Titanium.Cloud.Users module. Documentation itself shows how to query users.

Related

Setting an empty array index

i have an array that holds student answers for given questions.
if a student gives an answer, it gets inserted into the array at the current index like answers[questionindex] = answer
later, i can read the array and map the entries to the given question-array
this case:
[
"answer",
undefined, // student has not given answer
"answer2",
]
works. (looping over the array, simply outputting "no answer given" if (answers[questionindex] === undefined)
but it doesn't work when the LAST answers were undefined (1 or more)
they just don't exist (of course).
how can i set those fields to undefined (like, after a timer reaches zero), to show that there was no answer given?
right now, the average-calculation shows 100% correct for 3 given (correctly), then 2 not given at all
code
var testResults = {
addRoom: function(Id, teacher) { // room pseudoconstructor
this[Id] = {
created: moment(),
runningProblem: false,
time: 0, // holds the countdown for the current problem
getTime: function() { // returns the countdown-counter
return this.time;
},
Id: Id,
teacher: teacher,
getCurrentSolution: function() {
return math.eval(this.testProblems[this.getCurrentProblemIndex()].problem);
},
getTimeTaken: function() {
return this.getCurrentProblemTimeLimit() - this.time;
},
getCurrentProblemTimeLimit: function() {
return this.testProblems[this.getCurrentProblemIndex()].timeLimit;
},
getCurrentProblemIndex: function() {
return this.testProblems.length - 1;
},
addTestProblem: function(problem, timeLimit) {
var solution = math.eval(problem);
this.testProblems.push({problem: problem, timeLimit: timeLimit, solution: solution});
console.dir(this.testProblems);
},
testProblems: [],
updatePercentages: function(name) {
function round(num) {
return +(Math.round(num + "e+2") + "e-2");
}
console.log('updating percentages');
console.log('answers length ' + this.students[name].givenAnswers.length);
var timeSum = 0;
for(var i = 0; i < this.students[name].givenAnswers.length; i++ ) {
timeSum += this.students[name].givenAnswers[i].takenTime;
}
var timeAvg = timeSum / this.students[name].givenAnswers.length;
console.log('timeAvg for ' + name + ' ' + timeAvg);
this.students[name].avgTime = round(timeAvg);
var correctSum = 0;
for(var j = 0; j < this.students[name].givenAnswers.length; j++ ) {
if (this.students[name].givenAnswers[j].correct) {
correctSum++;
}
}
var correctAvg = correctSum / this.students[name].givenAnswers.length;
console.log('correctAvg for ' + name + ' ' + correctAvg);
this.students[name].avgCorrect = round(correctAvg) * 100;
},
addGivenStudentAnswer: function(name, answer, takenTime, index) {
console.log('adding answer ' + name + ' ' +answer+ ' ' + takenTime);
var correct = this.getCurrentSolution() == answer;
if (typeof this.students[name].givenAnswers[index] === 'undefined') {
this.students[name].givenAnswers[index] = ({
answer: answer,
takenTime: takenTime,
correct: correct
});
this.updatePercentages(name);
//console.dir(this.students[name].givenAnswers);
return true;
} else {
console.log('attempt at double answer. not saved');
return false;
}
},
addStudent: function(name) {
if (!(this.students[name])) {
this.students[name] = {
studentName : name,
avgTime: 0,
avgCorrect: 0,
givenAnswers: []
}
}
console.dir(this);
},
students: {}
};
console.dir(this);
},
deleteRoom: function(Id) {
delete this[Id];
console.log('room deleted from testResults');
}
};
// after test
var name = socket.userName;
var room = socket.room;
var created = testResults[room].created;
var students = testResults[room].students;
var problems = testResults[room].testProblems;
var test = new tests({
roomId : room,
created : created,
teacher : name,
students : students,
problems : problems
});
test.save(function(err, result) {
if (err) {console.log(err);}
else {
console.log('test saved to DB');
socket.emit('testSaved');
// delete from roomList
testRooms.deleteRoom(room, name);
// delete from resultObject
testResults.deleteRoom(room);
// answer
io.in(room).emit('room Closed');
}
});
route for reading a test from DB afterwars
router.get('/showtests/:roomId', function(req, res) {
if (req.user && req.user.role === 'teacher') {
tests.findOne({roomId: req.params.roomId}, {}, function(err, result) {
if (err) {console.log(err);}
res.render('showSingleTest', {user: req.user, testData: JSON.parse(JSON.stringify(result))});
})
} else {
res.render('customerror', { title: "Error", errMsg1: "error.error", errMsg2: "error.notLoggedIn" });
}
});
aaaaaand the jade
h2(data-i18n="markup.studentsAnswers")
each student in testData.students
.testViewSingleStudentAnswers.col-md-6
h3 #{student.studentName}
ol.answers
each answer in student.givenAnswers
if (answer)
if (answer.correct == true)
li.correct
span #{answer.answer}
|
span.floatRight (#{answer.takenTime}s)
else
li.wrong
span #{answer.answer}
|
span.floatRight (#{answer.takenTime}s)
else
li.noAnswer(data-i18n="markup.noAnswerGiven")
.testTotals
| #{student.avgCorrect}
span(data-i18n="markup.percentCorrect")
| ,
| #{student.avgTime}
span(data-i18n="markup.avgTime")
You can do like so:
function push_answer(answer){
answer = answer || "undefined"
array_of_answers.push(answer)
}
Now, the value is not undefined, but it's defined by the literal. You can replace it with some unicode character in case some answer can be "undefined".
Have a nice day!
Seems to be working without issue for me.
HTML:
<div id="content">
</div>
JS:
var answers = ["answer1","answer2",undefined,"answer3",undefined];
for(i=0;i<answers.length;i++) {
if(!answers[i]){
answers[i]="no answer";
}
}
document.getElementById('content').innerHTML = answers;
jsFiddle
My personal recomendation: "Never leave things to chance"
if the student doesn't choose an answer, you should fill that blank space with a '', because undefined is really annoying to handle, so in order to fill the gaps:
This will check if answer is "undefined" and fill the gap with a '' (blank), then, when you check that answer, is going to be more simple to evaluate...
if(answer)
answers[questionindex] = answer;
else
answers[questionindex] = '';

TypeError: Cannot read property 'name' of undefined

Post.find({}, function (error, data){
var proj = [];
for (var i = 0; i < data.length; i++) {
proj.push({
image: "none",
name: "none",
pPic: "none",
profession: "none"
});
}
// reverse post order
function aSyncLoop(i, callback) {
if (i>=0){
proj[data.length-i-1].image = data[i].imagelink[0];
User.find({'_id' : data[i].author}, function(error, userdata){
proj[data.length-i-1].name = userdata.local.name+ " " + userdata.local.surname;
});
aSyncLoop(i-1, callback);
} else { callback(); }
}
aSyncLoop(data.length-1, function() {
console.log('callback');
});
The error happens here:
proj[data.length-i-1 ].name = userdata.local.name+ " " + username.local.surname;
I guess the problem relies on the assignment being inside a Find query but i wouldn't know how to fix it.
The "userdata" returned from .find() is an "array" and not a singular object.
The easy fix is to use .findOne() when you only expect a single result, such as fetching by the primary key. Better yet, .findById():
User.findById(data[i].author, function(error, userdata){
console.log(userdata);
proj[data.length-i-1].name = userdata.local.name+ " " + userdata.local.surname;
});

How properly handle async functions in nodejs

I am new to nodejs, and I don't properly understand how async functions works. I read about them a lot today, but I cant solve my problem.
I use Sequelize.js as the ORM and my problem is when I nest a query into the callback of an other query then I cant force it to continues only when both query ended.
Here is my current code:
io.on('connection', function (socket) {
socket.on('join', function (data) {
clients[clients.length] = new Client("Client " + clients.length, data.channel);
console.log('Client connected Channel: ' + clients[clients.length-1].channel);
var array = []
DB.Matches.findAll({attributes: ['matchId', 'teamAId', 'teamBId']}).then(function (result) {
for (var i = result.length - 1; i >= 0; i--) {
DB.Teams.findAll({where: { team_id: [result[i].teamAId,result[i].teamBId]}}).then(function (teams) {
array.push({ id: 0, name: teams[0].clubName + ' - ' + teams[1].clubName});
}).then(function () {
// Now my emit event is here but I dont want to run every time the loop run
console.log(array);
socket.emit('matches', array);
});
}
}.then(function () {
// I tried to put it here, but then I got an empty array, because the queries haven't finshed yet
}));
});
});
When this code is called, the array will be emited in every loop with one more element in it in every loop, but this is not good for me. I want to call the emit event once when the array is totally filled.
The preferred way of solving this kind of thing is to use Promise.all
io.on('connection', function (socket) {
socket.on('join', function (data) {
clients[clients.length] = new Client("Client " + clients.length, data.channel);
console.log('Client connected Channel: ' + clients[clients.length-1].channel);
DB.Matches.findAll({attributes: ['matchId', 'teamAId', 'teamBId']}).then(function (result) {
var promises = [];
for (var i = result.length - 1; i >= 0; i--) {
promises.push(
DB.Teams.findAll({where: { team_id: [result[i].teamAId,result[i].teamBId]}}).then(function (teams) {
return { id: 0, name: teams[0].clubName + ' - ' + teams[1].clubName};
}));
}
Promise.all(promises).then(function(array) {
console.log(array);
socket.emit('matches', array);
});
});
});
});
edit:
If I understand you correctly you want to write
return { id: result[i].matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
But that doesn't work. That line of code is executed at some point in the future,
i.e. after the for loop has finished and by that time i is -1.
To make it work you need a new variable for each iteration of the loop.
You could do that e.g. by wrapping the code in another function like this
for(var i = result.length - 1; i >= 0; i--) {
(function(i) {
promises.push(
DB.Teams.findAll({where: { team_id: [result[i].teamAId,result[i].teamBId]}}).then(function (teams) {
return { id: result[i].matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
}));
})(i);
}
That way you use a different i variable (stored at a different place in memory) in each iteration.
But the best way to do it in this case is to use forEach. The only difference is that the loop will
iterate through the array forward and not backward as was the case with your for loop.
result.forEach(function(match) {
promises.push(
DB.Teams.findAll({where: { team_id: [match.teamAId,match.teamBId]}}).then(function (teams) {
return { id: match.matchId, name: teams[0].clubName + ' - ' + teams[1].clubName};
}));
});

How can I get specific data from JSON?

How can I get specific data from JSON?
JSON:
[
{ "TotalPageCount": 66 },
{ "TotalTitleCount": 199 },
{ "Title": "cola" },
{ "Title": "elvis tom" },
{ "Title": "dvd" }
]
Javascript Code:
<script>
function updateTitlesArea() {
$.getJSON(
"/lates/json/",
null,
function(data) {
$("#titlesDiv").html("");
$("#pagesDiv").html("");
var x;
if (data.length > 0) {
for (x in data) {
$("#titlesDiv").html($("#titlesDiv").html() +
"<li>" + data[x].Title + "" +
"</li>"
);
}
} else {
$("#titlesDiv").html("<li>no entry</li>");
}
});
}
</script>
I'm trying to get {"TotalPageCount":66} AND {"TotalTitleCount":199}
from Javascript. Please provide me a method to get them?
Thanks a lot.
Update
Something going wrong, I tried all solutions but not worked fine.
I have control on json format:
Current Json Builder:
if (title.Any())
{
foreach (var x in title)
{
result.AddLast(new { Title = x.Title });
}
}
result.AddLast(new { TotalPageCount = totalPageCount });
result.AddLast(new { TotalTitleCount = totalTitleCount });
return Json(result.ToList(), JsonRequestBehavior.AllowGet);
I made a small change in json format, took totalpage and title count to end of json.
Current:
[{"Title":"kola"},{"Title":"yilmaz
ozdil"},{"Title":"dvd"},{"Title":"truly madly
deeply"},{"Title":"deportivo de la coruna"},{"Title":"sizi seven
kisiyle sevdiginiz kisinin farkli olmasi"},{"Title":"kadinlarin bavul
gibi canta tasimalari"},{"Title":"hosbuldum"},{"Title":"sark
cibani"},{"Title":"mevsimler gecerken"},{"Title":"bir kerede kolon
gibi sicmak"},{"Title":"gelismek"},{"Title":"faz ve alasim
bilimi"},{"Title":"memetq"},{"Title":"ogrencilerin sinav kagidina
dustugu ilginc notlar"},{"Title":"cami duvarina
isemek"},{"Title":"kufurden sonra tovbe etmek"},{"Title":"gida tarim
ve hayvancilik bakanligi"},{"Title":"cevre orman ve sehircilik
bakanligi"},{"Title":"google da nikah masasi
calmak"},{"TotalPageCount":9},{"TotalTitleCount":199}]
With my code and given examples I still couldn't get the TotalPageCount and TotalTitleCount.
For the record: Maybe next time I can add more attributes next to Title.
So I would like to keep that json format.
Thanks for advance
When you do x in data you get every key of objects. So you have to do a simple check if it's TotalPageCount or TotalTitleCount. Like this;
<script>
function updateTitlesArea() {
$.getJSON(
"/lates/json/",
null,
function(data) {
var x, totalPageCount, totalTitleCount;
$("#titlesDiv").html("");
$("#pagesDiv").html("");
if (data.length > 0) {
for (x in data) {
if('TotalPageCount' == x) {
totalPageCount = data[x];
continue;
}
if('TotalTitleCount' == x) {
totalTitleCount = data[x];
continue;
}
$("#titlesDiv").html($("#titlesDiv").html() +
"<li>" + data[x].Title + "" +
"</li>"
);
}
// You can do here whatever you want with 'totalPageCount' and 'totalTitleCount'
} else {
$("#titlesDiv").html("<li>no entry</li>");
}
});
}
</script>
It's an array, so
if (data.length > 0) {
var obj = data[0]; // array, not object
for (key in obj) {
$("#titlesDiv").html(
$("#titlesDiv").html() +
"<li><a href=\"/" + obj[key].Title.replace(/ /g, '-') + "\">" +
obj[key].Title + "</a>" +
"</li>"
);
}
Are you using jQuery right? You can try something like this:
var prom = $.getJSON('/lates/json/'),
ar;
prom.then(function (data) { ar = data; });
After that, you will have the response array in ar. You will be able to access to your required values in this fashion:
ar[0].TotalPageCount
ar[1].TotalTitleCount
I hope this will help you. Good luck.
With your current JSON format, it'd be something like this. It'd be better if you could change the JSON format, though.
<script>
function updateTitlesArea() {
$.getJSON(
"/lates/json/",
null,
function(data) {
$("#titlesDiv").html('<ul></ul>'); // <li> goes inside <ul> or <ol>
$("#pagesDiv").empty();
var has_titles = false;
for(var i = 0; i < data.length; i++) {
if("Title" in data[i]) {
$("#titlesDiv ul").append(
'<li>' + data[i].Title + "" +
"</li>"
);
has_titles = true;
}
}
if( !has_titles ) {
$("#titlesDiv ul").html("<li>no entry</li>");
}
}
);
}
</script>

Issue while getting array value in NodeJS

I am using NodeJS to count the number of employees in different section. I am using Mongoose as ODM and MongoDB as database.That is my code (very simple for testing purposes).
exports.list= function( req, res){
var array = ['sectionA', 'sectionB'];
var i;
for(i = 0; i<array.length; i++){
Issue.count({ 'section.name': array[i]}, function (err, count) {
console.log('Section name is: ' + array[i] + ' number of employees: ' + count );
)};
}
}
But the value of array[i] is undefined inside Issue.count({ 'section.name': array[i]}, function (err, count) {});. But the value of count is absolutely right. I want an output like:
Section name is: sectionA number of employees: 50
Section name is: sectionB number of employees: 100
But my current output is
Section name is: undefined number of employees: 50
Section name is: undefined number of employees: 100
This is because value of i inside Issue.count({ 'section.name': array[i]}, function (err, count) {}); is always 2.
Is it possible that Issue.count function is asynchronous? So your loop is completing before the callback of:
function (err, count) {
console.log('Section name is: ' + array[i] + ' number of employees: ' + count );
}
is executed. When the callbacks are executed the value of i is undefined as a result.
#eshortie is correct: Issue.count is asynchronous and that's causing the problem.
Here's a solution:
for (i = 0; i<array.length; i++) {
Issue.count({ 'section.name': array[i]}, function(sectionName, err, count) {
console.log('Section name is: ' + sectionName + ' number of employees: ' + count );
}.bind(null, array[i]));
}
Don't try to execute asynchronous functions using a regular for loop. It is asking for problems. Use async.eachSeries or async.each instead https://github.com/caolan/async#eachseriesarr-iterator-callback
var async = require('async')
var Issue = {} // mongoose isue model here
var elements = ['foo', 'bar']
async.eachSeries(
elements,
function(name, cb) {
var query = {
'section.name': name
}
Issue.count(query, function(err, count) {
if (err) { return cb(err) }
console.dir(name, count)
})
},
function(err) {
if (err) {
console.dir(err)
}
console.log('done getting all counts')
}
)
Using Q library
var Q = require('q')
var i = 0;
function hello (item){
var defer = Q.defer();
Issue.count({'section.name': student}, function (err, count) {
if(err){
defer.reject(err);
}else{
var result = 'Section name is: ' + item + ' number of employees: ' + count ;
defer.resolve(result)
}
});
})
return defer.promise;
}
function recall(){
hello(checkItems[i]).then((val)=>{
console.log(val)
if(i < checkItems.length - 1){
i++
recall();
}
})
}
recall()

Categories