In AngularJs set a variable in forEach for each object - angularjs

I am trying to run a forEach function with data from a query and I want to set a variable for each object in that data to be able to use in a ng-repeat. I keep overriding the variable and cannot wrap my head around setting the variable for each one.
CategoryCardService.query({}, function (data) {
$scope.categoryCards = data;
angular.forEach(data, function (value) {
var categoryOccupancyPercent = $filter('number')(value.occupancy_percent * 100, 0);
var categoryTotalTurnover = value.total_turnover;
var doughnut_chart_min = 0;
var doughnut_chart_max = 0;
doughnut_chart_min = categoryOccupancyPercent;
doughnut_chart_max = 100 - categoryOccupancyPercent;
data.doughnutData = [doughnut_chart_min, doughnut_chart_max];
data.display = categoryOccupancyPercent + '%';
});
});

Pass in the key and assign like that.
CategoryCardService.query({}, function (data) {
$scope.categoryCards = data;
angular.forEach(data, function (value, key) {
// ...
data[key].display = categoryOccupancyPercent + '%';
});
});

Related

How to change [] with {} in my array object

I retrieve this data from an API
{"city":"New York","type":["0","1","9"]}
I need to convert in this way:
{"type":{0:true,1:true,9:true},...}
I try with angular foreach in this way
var tmparr = [];
angular.forEach( $scope.path.type, function (value, key) {
tmparr.push(value + ":true")
});
$scope.checkfilters.type = tmparr
but in this way i have this result and it's not what i need
{"business_type":["0:true","1:true","9:true"]}
I don't know how to replace the [] with {} in my array
If I try to set var tmparr = {} I have undefined error in push function
Use bracket syntax
var tmparr = {};
angular.forEach( $scope.path.type, function (value, key) {
tmparr[value] = true;
});
$scope.checkfilters.type = tmparr;
You can loop through the type and then copy the values and assign it to true.
var original = {"city":"New York","type":["0","1","9"]};
var copy = {};
for(var i in original.type){
copy[original.type[i]] = true;
}
console.log(copy);
You can also use reduce with an object accumulator:
var data = {"city":"New York","type":["0","1","9"]}
const result = data.type.reduce((r,c) => (r[c] = true, r), {})
console.log(result)

how to access function parameter value inside nested AngularJS for each loop?

I am new for AngularJS and I am trying to access function parameter value inside nested angular for each loop , but that variable gets undefined error. here is my code .
var pieChart = function (_data, _fieldName) {
var data = _data;
var cost_max = 0;
var cost_min = 99999;
angular.forEach(groupBy($scope.api_data, _fieldName), function (obj, index) {
var total = 0;
var name = '';
angular.forEach(obj, function (row, i) {
name = row._fieldName;
total += 1;
})
data.push([name, total]);
if (cost_max < obj.cost) cost_max = obj.cost;
if (cost_min > obj.cost) cost_min = obj.cost;
})
$scope.chart.data = data;
$scope.loaded = 1;
}
row._fieldName is undefined here , what was the issue ? kindly help me.
var groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
In your second angular.forEach loop, you have to replace row._fieldName with row[_fieldName].
angular.forEach(obj, function (row, i) {
name = row[_fieldName];
total += 1;
})
By writing row._fieldName, you try to get the key named _fieldName from object row instead of the real field.
Little JSFiddle

AngularJS promise through tow loops

Have some trouble with Angular promise between two loops... First loop walk through an array of value, and for each value, make a PouchDB Query to retrieve some datas. Finally, would like to return to controller a JSON Object that would look like :
{
items: [
{
"attribute": "some value"
},
{
"attribute": "some other value"
},
...
],
"a_total": "some_total",
"another_total": "some_other_total"
}
In this object, "items"
Basically, put the code in a function that looks like :
var _stockByAreas = function(){
var deferred = $q.defer();
var data = {}; // Final datas to return to controller
// Get first array to loop into
var storageAreas = storageAreaService.storageAreaList();
var areas = []; // All of area
// Walk across array
angular.forEach(storageAreas, function(zone){
var area = {}; // First object to return
area.id = zone.id;
area.libelle = zone.libelle;
// Then make a PouchDB query to get all datas that involved
MyKitchenDB.query(function(doc, emit){
emit(doc.storage);
}, { key: area.id, include_docs: true }).then(function (result) {
area.sRef = "tabsController.addTo({id: '" + area.id + "'})";
area.nbProduct = 0;
area.totalQuantity = 0;
area.totalValue = 0;
// ... process result
if(result.rows.length > 0){
// Some results, so... let's go
area.sRef = "tabsController.outFrom({id: '" + area.id + "'})";
var rows = result.rows;
// Counter initialization
var total = 0;
var value = 0;
angular.forEach(rows, function(row){
total++;
var stocks = row.doc.stock;
angular.forEach(stocks, function(stock){
var nearOutOfDate = 0;
var nearStockLimit = 0;
quantity += stock.quantity;
value += stock.quantity * stock.price;
// Evalue la date de péremption
var peremptionDate = moment(stock.until);
var currentDate = moment();
if(currentDate.diff(peremptionDate, 'days') <= 1){
nearOutDate += 1;
}
});
area.nbProduct = total;
area.qteTotale = quantity;
area.valeur = value;
if(quantite == 1){
nearLimitOfStock += 1;
}
areas.push(area); // Add result to main array
});
}
}).catch(function (err) {
// Traite les erreurs éventuelles sur la requête
});
/**
* Hey Buddy... what i have to do here ?
**/
data.items = areas;
data.nearLimitOfStock = nearLimitOfStock;
data.nearOutOfDate = nearOutOfDate;
});
deferred.resolve(data);
return deferred.promise;
}
... But, console returns that "areas" is not defined, and other value too...
I think i don't really understand how promises runs...
Someone is abble to explain why i can't get the result that i expect in my case ?
Thx
Your code is too long, I just give you the approach.
Use $q.all() to ensure all your queries are completed. And use deferred.resolve(data) whenever your data for each query is arrived.
var _stockByAreas = function() {
var query = function(zone) {
var queryDef = $q.defer();
// timeout is for query and response simulations
setTimeout(function() {
// ...
queryDef.resolve( {data: 'MeTe-30'} );
}, 1000);
return queryDef.promise;
}
var promises = [];
angular.forEach(storageAreas, function(zone) {
// ...
promises.push( query(zone) );
});
return $q.all(promises);
}
_stockByAreas().then(function(res) {
// res[0] resolved data by query function for storageAreas[0]
// res[1] resolved data by query function for storageAreas[1]
// ...
});

AngularJs ForEach Loop only Shows last Object when pushed into new Object

I am using the forEach to loop through it iterates through all of the objects but only writes the last one to the new object of log{}.
My Javascript
$http.get('data.json').success(
function (info) {
var log = {};
log.id= info.id;
log.profile = {};
angular.forEach(info.profile, function (value, key) {
console.log(key,value)
log.profile.inter = value.inter
}, log);
console.log(JSON.stringify(log));
}
);
Deprecation Notice
The $http legacy promise methods .success and .error have been deprecated. Use the standard .then method instead.1
$http.get('data.json')
.then(function onFulfilled(response) {
var info = response.data;
var log = {};
log.id= info.id;
log.profile = {};
angular.forEach(info.profile, function (value, key) {
console.log(key,value);
log.profile[key] = value.inter;
});
console.log(JSON.stringify(log));
}).catch ( function onRejected(response) {
console.log("ERROR ", response.status;
});
To save values into an associative array, use the key as the property accessor. For more information, see MDN JavaScript Reference -- Property Accessors
log.profile[key] = value.inter;
Well the reason is that you are not using an array, you need to push values into an one.
$http.get('data.json').success(
function (info) {
var log = {};
log.id= info.id;
log.profile = {};
log.profile.inter = []; //definition of array
angular.forEach(info.profile, function (value, key) {
console.log(key,value)
log.profile.inter.push(value.inter); //add values in array defined behind
}, log);
console.log(JSON.stringify(log));
}
);
There are more solutions, but for now putting values in array is enough.
var log = {};
log.id= info.id;
log.profile = {};
log.profile.inter = []; //definition of array
angular.forEach(info.profile, function (value, key) {
console.log(key,value)
//needed to add key
log.profile[key] = {};
}, log);
console.log(JSON.stringify(log));
}

Create an AngularJS factory / object to hold an array

How can I update this code to hold an array of values? I want to hold FIELDNAME and the VALUE.
I want to set / add to the list by doing the following - add a value to the array/list.
userFilters.setData(' lastname', 'smith');
userFilters.setData(' firstname', 'bob');
userFilters.setData(' Mi', 'D');
And have the object hold an Array of
'lastname','smith'
'firstname','bob'
'mi','D'
App.factory('userFilters', [function () {
var data = {};
var getData = function (field) {
return data[field];
};
var setData = function (field, value) {
data[field] = value;
};
return {
getData: getData,
setData: setData
}
}]);
You could recreate this fairly simply without any need for the methods you are creating.
Javascript Objects are designed to do exactly what you are looking for here.
App.factory('userFilters', function() {
return {};
});
Rather than using a getter and setter, you could instead get and set values with square bracket accessors.
// setting properties
userFilters['lastname'] = 'smith';
userFilters['firstname'] = 'bob';
userFilters['Mi'] = 'D';
// getting properties
userFilters['lastname']; // 'smith'
userFilters['firstname']; // 'smith'
If you want to be able to have full control of what happens at get/set time, you could look at intercepting these calls with internal getters and setters, providing you know the property names before hand.
Finally, you could also wrap your own get and set functions around the object in order to hide it. However, this would make more sense as a Service.
App.service('userFilters', function() {
var store = {};
this.get = function(key) {
return store[key];
};
this.set = function(key, value) {
store[key] = value;
};
});
If it's important that your factory/service exposes an array then I would recommend sticking to using an object to store keys and values, but adding an array export method.
App.service('userFilters', function() {
var store = {};
this.toArray = function() {
var records = [];
return Object.keys(store).map(function(key) {
records.push([key, store[key]]);
});
};
this.get = function(key) {
return store[key];
};
this.set = function(key, value) {
store[key] = value;
};
});
If you want to loop through the properties, you can use a for-in loop.
for(var key in userFilters) {
var value = userFilters[key];
console.log(key, value);
}
You can also check whether there any keys at all, using the Object.keys method.
Object.keys(userFilters); // ['lastname', 'firstname', 'Mi']
This will return an array of all the keys in the object. If it has length 0, then you know it's empty.
In order to use an array for storage you will need to update both getData and setData methods and define data as an array []:
App.factory('userFilters', [function () {
var data = [];
var getData = function (field) {
for(var i=0; i<data.length; i+=2) {
if(data[i] == field) {
return data[i+1];
}
}
return null;
};
var setData = function (field, value) {
data = data.concat([field, value]);
};
return {
getData: getData,
setData: setData
}
}]);

Resources