JS code returning error - javascript

I'm new to JS and i had to use it for Cloud Code Parse feature. I have a class called "user_picture", through the code i query all the objects and go through it's "City" attribute. i want the response to be an array of unique city names. Anyway, here is the code i'm working on:
Parse.Cloud.define("cities", function(request, response) {
var query = new Parse.Query("user_picture");
query.find({
success: function(results) {
var cities = new Array();
for (var object in results){
var tempArray = [object.get("city")];
if (cities.length > 0){
for (var i = 0; i < cities.length; i++){
if (cities[i].get("city") == object.get("city")) {
break;
} else if (i == cities.length-1) {
cities = cities.concat(tempArray);
}
}
}
}
response.success (cities);
}, error: function() {
response.error("Error");
}
});});
However, when i run this function i receive the following error:
Error: TypeError: Object 0 has no method 'get'
at query.find.success (main.js:15:30)
at Parse.js:2:5786
at r (Parse.js:2:4981)
at Parse.js:2:4531
at Array.forEach (native)
at Object.E.each.E.forEach [as _arrayEach] (Parse.js:1:666)
at n.extend.resolve (Parse.js:2:4482)
at r (Parse.js:2:5117)
at Parse.js:2:4531
at Array.forEach (native) (Code: 141, Version: 1.2.18)
And the response returns null. I tried printing one object from the results array in order to make sure i'm receiving the right query, and it's printing fine the city. What could be the problem?

The for in loop iterates through all the keys of an object literal. Since results is an Array it will iterate through the keys of the Array, which are '0', '1' etc.
This means that the object variable will hold those key vales. And since they are not objects they don't have a method called get.
You need a forEach loop instead.
results.forEach(function(object){
var tempArray = [object.get("city")];
if (cities.length > 0){
for (var i = 0; i < cities.length; i++){
if (cities[i].get("city") == object.get("city")) {
break;
} else if (i == cities.length-1) {
cities = cities.concat(tempArray);
}
}
}
}
});
Or if you're targeting ES3 then you should use a for loop
for(var i = 0, length = results.length; i< length; i++){
var object = results[i];
var tempArray = [object.get("city")];
if (cities.length > 0){
for (var i = 0; i < cities.length; i++){
if (cities[i].get("city") == object.get("city")) {
break;
} else if (i == cities.length-1) {
cities = cities.concat(tempArray);
}
}
}
}

I recall working with Parse objects a bit and there seemed to be times to access them as an object (by direct parameter access) and sometimes by using the get method and it looks like you're mixing up the array access and object (from Parse) access methods.
Also, your list generator doesn't seem like it's really building a unique list. You only check to see if the current city is the same as the city you're going to add.
I might do something more like this (for the success method):
function(parseResults) {
var cities = {};
var ii=0;
var nResults = parseResults.length
for(;ii<nResults;++ii) {
cities[result.get('city')] = 1
}
var citiesArray = cities.keys();
response.success(citiesArray);
}
What we do here is build up an object whose keys are city names. Then return the keys as an array. What this does for us is automatically build a unique list because object keys should be unique.
If the result.get gives you problems, try replacing it with result.city. But i suspect the error you were seeing with your first example was trying to call get on the Array element.

Related

Angularjs can't get array length

I am trying to get the array length, when i console log
console.log($scope.community)
I do get a return, but when i try doing the method i found online , like Get the object length in angularjs is undefined
var array = Object.keys($scope.community);
var len = array.length;
console.log(len)
I am returned with 0 and no error
Array call :
var all = displayAll.callAll()
.then(function(response) {
$scope.all = response;
for (var i=0; i< $scope.all.length; i++) {
if ($scope.all[i].CATEGORY == 'Community')
{
$scope.community.push($scope.all[i]);
}
var len = $scope.community.length;
console.log(len);
should return the length of the community.
Plus this method can also be used in Native JS, even without using AngularJS.

Updating the value of an object inside a loop using javascript

I'm currently facing a difficulty in my codes.
First i have an array of objects like this [{Id:1, Name:"AML", allowedToView:"1,2"}, {Id:2, Name:"Res", allowedToView:"1"}...] which came from my service
I assign it in variable $scope.listofResource
Then inside of one of my objects I have that allowedToView key which is a collection of Id's of users that I separate by comma.
Then I have this code...
Javascript
$scope.listofResource = msg.data
for (var i = 0; i < msg.data.length; i++) {
First I run a for loop so I can separate the Id's of every user in allowedToView key
var allowed = msg.data[i].allowedToView.split(",");
var x = [];
Then I create a variable x so I can push a new object to it with a keys of allowedId that basically the Id of the users and resId which is the Id of the resource
for (var a = 0; a < allowed.length; a++) {
x.push({ allowedId: allowed[a], resId: msg.data[i].Id });
}
Then I put it in Promise.all because I have to get the Name of that "allowed users" base on their Id's using a service
Promise.all(x.map(function (prop) {
var d = {
allowedId: parseInt(prop.allowedId)
}
return ResourceService.getAllowedUsers(d).then(function (msg1) {
msg1.data[0].resId = prop.resId;
Here it returns the Id and Name of the allowed user. I have to insert the resId so it can pass to the return object and it will be displayed in .then() below
return msg1.data[0]
});
})).then(function (result) {
I got the result that I want but here is now my problem
angular.forEach(result, function (val) {
angular.forEach($scope.listofResource, function (vv) {
vv.allowedToView1 = [];
if (val.resId === vv.Id) {
vv.allowedToView1.push(val);
I want to update $scope.listofResource.allowedToView1 which should hold an array of objects and it is basically the info of the allowed users. But whenever I push a value here vv.allowedToView1.push(val); It always updates the last object of the array.
}
})
})
});
}
So the result of my code is always like this
[{Id:1, Name:"AML", allowedToView:"1,2", allowedToView:[]}, {Id:2, Name:"Res", allowedToView:"1", allowedToView:[{Id:1, Name:" John Doe"}]}...]
The first result is always blank. Can anyone help me?
Here is the plunker of it... Plunkr
Link to the solution - Plunkr
for (var i = 0; i < msg.length; i++) {
var allowed = msg[i].allowedToView.split(",");
msg[i].allowedToView1 = [];
var x = [];
Like Aleksey Solovey correctly pointed out, the initialization of the allowedToView1 array is happening at the wrong place. It should be shifted to a place where it is called once for the msg. I've shifted it to after allowedToView.split in the first loop as that seemed a appropriate location to initialize it.

javascript conditions applied on independant objects

I'm going crazy for i do not understand the behavior of my loop!
here a sample of a json I read :
[{"type":"robot","town":"NANTES","region":"Ouest","performances":[{"date":YYYY-MM-DD","value":100},{...}],"availability":[{"date":"YYY-MM-DD","value":100},{...}]},{"type":"robot","town":"RENNES","region":"Ouest","performances":[{"date":YYYY-MM-DD","value":100},{...}],"availability":[{"date":"YYY-MM-DD","value":100},{...}]}
I create 2 objects :
REGIONS = {},TOWNS= {};
here is the function the moment i recieve the object:
function getRobotsDatas(robotList) {
for (var i = 0; i < robotList.length; i++) {
var robot = robotList[i];
// working on TOWNS object
//I check if the "town" object of TOWNS object already exist
if (TOWNS[robot.town] === undefined) {
// if not, i create it
TOWNS[robot.town] = {};
//then i push performances datas of my robot in my TOWNS.town object
TOWNS[robot.town].performances = robot.performances;
// the same for availability datas
TOWNS[robot.town].availability= robot.availability;
}
// then I work nearly the same way on REGIONS object.
//i check if the "region" object exist in REGIONS object. If not, i create it and add the perf+availability datas of the robot.
if (REGIONS[robot.region] === undefined) {
REGIONS[robot.region] = {};
REGIONS[robot.region].performances = robot.performances;
REGIONS[robot.region].availability= robot.availability;
}
// If the REGIONS.region already exist, i just want to add the datas of performances and availability in the already existing arrays of REGIONS.region (performances[] and availabilities[])
else {
for (var j = 0; j < robot.performances.length; j++) {
REGIONS[robot.region].performances.push(robot.performances[j]);
}
for (var k = 0; k < robot.availability.length; k++) {
REGIONS[robot.region].availability.push(robot.availability[k]);
}
}
}
The problem is that the condition for an already existing "REGIONS.region" is also applied on TOWNS. It adds values of performances and availabilities in the TOWNS objects of the robots which have the same value of the "region" attribut.
for example, in the sample i gave at the beginning, i'll find availabilities and perf datas in a new object : REGIONS.Ouest {performances:[...], availability:[...]}, but i will also find NANTES' perf an availibilities datas in RENNES' perf and availabilities arrays... and THAT, i don't want!
What's wrong with my condition / loop!???
Your code refers to 'town' but your incoming JSON has 'ville' instead.
I appreciate that this won't fix the problem, but the example should at least be correct.
The incoming JSON has two sub-objects. For each one, you test for presence in your Towns and Regions data structures. If they don't each have a matching entry, you are creating one, and then adding entries in the two further sub-objects (performances and availability).
If you don't want this in both cases, you need to test the incoming JSON appropriately.
This is a problem of variable Reference. try this simple change JSON.parse(JSON.stringify(xxx))
function getRobotsDatas(robotList) {
for (var i = 0; i < robotList.length; i++) {
var robot = robotList[i];
if (TOWNS[robot.town] === undefined) {
TOWNS[robot.town] = {};
TOWNS[robot.town].performances = JSON.parse(JSON.stringify(robot.performances));
TOWNS[robot.town].disponibilite = JSON.parse(JSON.stringify(robot.availability));
}
if (REGIONS[robot.region] === undefined) {
REGIONS[robot.region] = {};
REGIONS[robot.region].performances = robot.performances;
REGIONS[robot.region].availability= robot.availability;
}
else {
for (var j = 0; j < robot.performances.length; j++) {
REGIONS[robot.region].performances.push(robot.performances[j]);
}
for (var k = 0; k < robot.availability.length; k++) {
REGIONS[robot.region].availability.push(robot.availability[k]);
}
}
}
}
JS is funny.... :)

My update tag function here isn't working

Hi all I am new to angular and would like to know what I am doing wrong in this function.
I am trying to retrieve a firebase child array of tags and compare it with users tags and get an union and post that union back to the firebase array .
Here is my function:
//this retrieved the tag arrays from firebase
$scope.utags = Tag.gettag();
This function converts a firebase array to a JS array .. I initialize it with {{universaltags(utags)}} from the view. Any attempt to initiate the function in the controller using $scope.unversaltags($scope.utags); gives me a blank array
but it works with the views initiation.
$scope.universaltags = function(utag){
var arr1 = [];
for (var i = 0 ; i < utag.length; i++) {
arr1.push(utag[i].$value);
}
return arr1;
};
Also this is the function which I use to find the union and post it back to firebase.
$scope.universaltagupdate = function union_arrays (x,y,Tag) {
var obj = {};
for (var i = x.length-1; i >= 0; -- i) {
obj[x[i]] = x[i];
}
for (var i = y.length-1; i >= 0; -- i) {
obj[y[i]] = y[i];
}
var res = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) { // <-- optional
res.push(obj[k]);
}
}
//this uses a service to set firebase value
return Tag.updatetag(res);
}
I am not able to initialize both the functions within the controller.
Can you please tell me what is wrong with this approach and what can be the best way to achieve the result? Right now using the functions in curly braces show the results, but how do I accomplish this in the controller?

Why do the arrays I'm creating within my loop not contain all the values I've added after the loop completes?

I have an array in Java Script that I'm trying to split into two arrays using a test within a loop. The console is logging that the two objects are being stored, but after the loop finishes the inhaledArray array only contains one object.
for (var i=0; i<results.length; i++)
{
var inhaledArray = new Array();
var otherArray = new Array();
if(results[i].get('MedicationType') == "inhaled")
{
//inhaledArray is dumping results
console.log(results[i]);
inhaledArray.push(results[i]);
}
if(results[i].get('MedicationType') == "other")
{
otherArray.push(results[i]);
}
}
You are resetting the output at every iteration (by pointing the variable to a new array).
Move the array setup code outside of the loop.
Alex already answered your question, but here's a suggestion. If you ever have a bunch of arrays that store basically the same data, consider using an object instead:
var categories = {};
for (var i = 0; i < results.length; i++) {
var name = results[i].get('MedicationType');
if (name in categories) {
categories[name].push(results[i]);
} else {
categories[name] = [results[i]];
}
}
console.log(categories.inhaled);
console.log(categories.other);
That way, you can account for all of the category types without hard-coding anything.
this is because you are initializing the array inside the forloop, just move the Array initialization before the for loop like below
var inhaledArray = new Array();
var otherArray = new Array();
for (var i = 0; i < results.length; i++) {
if (results[i].get('MedicationType') == "inhaled") {
//inhaledArray is dumping results
console.log(results[i]);
inhaledArray.push(results[i]);
}
if (results[i].get('MedicationType') == "other") {
otherArray.push(results[i]);
}
}

Categories

Resources