Restangular: Empty array using $object - angularjs

I display my data in a table (smart-table) and everything is working well but in my angular code, when I try to get my "topicList" it's return an empty array. there is my code and thank you in advance.
$scope.topicList= Restangular.all("topic").getList().$object;
for(var k in $scope.topicList) {
console.log($scope.topicList[k]);
if($scope.topicList[k] === "")
{xxxx}
}

Restangular.all('topic').getList().then(function(response) {
$scope.topicList = response;
...
});
After you've assigned the topicList then you can do your bits and pieces.

Related

angularjs check if key allready exist and if not exist push it to scope inside foreach loop

im geting data from Db using php at first for building a table , later im geting new json data from socket and updating $scope, what i need is to push values that not exist in $scope.
angular.forEach(event.market, (market ,keym) => {
angular.forEach($scope.users.results, function(value, key) {
if(value.marketId == keym) // keym = new marketId from socket
{
//do nothing
}
else
{
//push(new valuse);
}
});
});
the problem im having is that if a marketId dosent match any keys that i allready have then it pushes the amount of times it didnt match instead of pushing 1 time if it didnt match.
what am i doing wrong?
thanks
Before doing push into some array, check whether marketId dose not match any keys and not present in array as well. So in else you will have to add conditions for marketId check and array check.
From what I understand you want to add in an array, missing objects. I think what you are trying to do can be simply achieved by:
angular.forEach(event.market, (valueM, keyM) => {
let isDuplicate = $scope.users.results.filter(user => /* some validation here */).length > 0;
if(!isDuplicate) {
// push new values
}
})
that solved my issue :
angular.forEach(game.market, (market, keym) => {
var addToArray = true;
for (var i = 0; i < $scope.users.results.length; i++) {
if ($scope.users.results[i].marketId == keym) {
addToArray = false;
}
}
if (addToArray) {
$scope.users.results.push({
marketId: keym,
marketName: market.name
});
}
$scope.users.results.marketName = ' ';
$scope.users.results.marketId = ' ';
});
thanks

Elements won't be pushed to array inside stream()

When I try to do console.log(recommendedTasks) inside the if condition it works but outside the array remains empty
There is the code I've tried for:
let recommendedTasks = [];
Task.find({}).stream()
.on('data', function(task){
for(let skill of member.skills){
for(let skill2 of task.skills){
if(String(skill) == String(skill2)) recommendedTasks.push(task._id);
}
}
});
console.log(recommendedTasks)
This should be a comment but I dont have those privalages.
It should be because the console.log is being called in a for loop.
The following code should work.
for (i = 0; i < recommendedTasks.length; i++) {
console.log(recommendedTasks[i])
}
Again I wish I could comment. Hope this helps you!
This is happening because you define recommendedTasks outside Task function which triggers at same time as console.log() which takes the first value available [], try this instead.
Task.find({}).stream()
.on('data', function(task){
let recommendedTasks = [];
for(let skill of member.skills){
for(let skill2 of task.skills){
if(String(skill) == String(skill2)) return recommendedTasks.push(task._id);
}
}
});
console.log(recommendedTasks)
Hope it helps.

AngularJS: How to create new arrays from JSON response?

I have a function tied to the factory for my controller:
fac.GetDailyCountersList = function () {
return $http.get('/Data/GetDailyCountersList')
}
Inside the controller, here's where the function is called:
$scope.DailyCounters = null;
DailyCounterService.GetDailyCountersList().then(function (d) {
$scope.DailyCounters = d.data;
}, function (error) {
alert('Error!');
});
Based on this, if I were to output the variable on the html page, this would show:
[{"Id":1,"MIDay":"16","MITime":"900","MICounter":0},
{"Id":2,"MIDay":"16","MITime":"915","MICounter":1},
{"Id":3,"MIDay":"16","MITime":"930","MICounter":0},
{"Id":4,"MIDay":"17","MITime":"945","MICounter":0},
{"Id":5,"MIDay":"17","MITime":"1000","MICounter":0},
{"Id":6,"MIDay":"17","MITime":"1015","MICounter":52},
{"Id":7,"MIDay":"18","MITime":"1030","MICounter":2},
{"Id":8,"MIDay":"18","MITime":"1045","MICounter":3},
{"Id":9,"MIDay":"18","MITime":"1100","MICounter":0}]
My question is how to take this data and create other arrays based on one of the properties of the Json data.
For example, how would I put arrays
{"Id":1,"MIDay":"16","MITime":"900","MICounter":0},
{"Id":2,"MIDay":"16","MITime":"915","MICounter":1},
{"Id":3,"MIDay":"16","MITime":"930","MICounter":0}
Into a new array "ArrayDay16"? And the rest into their respective arrays as well.
I was thinking about doing it this way:
var myArray = [];
if (d.data['MIDay'] == '16')
myArray.push(d.data);
But this is incorrect/fails. Any ideas for an efficient solution?
Use the filter function to populate new arrays. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
//This will populate "someArray" with only the data that has MIDAY = 16
DailyCounterService.GetDailyCountersList().then(function (d) {
$scope.someArray = d.data.filter(function(ele) {
return ele.MIDAY === '16';
});
}
You can use the filter function:
var daySixteen = data.filter(function (d) { return d.MIDay === "16"; });
you can try the next:
d.data.foreach(function(item){
if(item.MIDay == 16)
myArray.push(d.data);
});
If you want to be efficient you should do this on the back end with constraint(s). It's not the browsers job.
Although, if you still want it to filter it on the front end you could use the filter-function with some lamdba expressions
var newList = oldList.filter(i => i["MIDay"] == "16");

Knockout tree - get all selected items in tree

Here's the fiddle
I have a tree structure of clients that I'm binding to an unordered list, and each client may or may not have a SubClient. I've added the ability to select an item in the list but now I cannot figure out how to loop through the tree and get an array of all the selected items.
In particular, this beast is where I'm having problems:
cp.GetSelectedClientsArray = function (clients) {
var selected = [];
ko.utils.arrayForEach(clients, function (item) {
if (item.IsSelected()) {
selected.push(item.ClientName());
}
ko.utils.arrayForEach(item.SubClient(), function (subItem) {
if (subItem.IsSelected()) {
selected.push(subItem.ClientName());
}
cp.GetSelectedClientsArray(subItem);
});
});
console.log(selected);
return selected;
};
After I toggle the IsSelected() observable I'd like to loop through the list and get an array with only the selected items.
I've written and re-written this more than a few times, and could really use some help. I'm not even sure how to write a recursive function that would work, because every time I call the function from within, it wipes out my "selected" array and setting it as a global variable keeps any item that has ever been selected in the array.
Any help is appreciated
Here's recursive version
cp.GetSelectedClientsArray = function (clients) {
var result = [];
function GetSelected(clients){
for (var i in clients){
if(clients[i].IsSelected()){
result.push(clients[i].ClientName());
}
GetSelected(clients[i].SubClient());
}
}
GetSelected(clients);
console.log(result);
return result;
};
See jsfiddle
If I understand correctly what you are trying to do, why not try something like this?
_self.SelectedClient = ko.observableArray();
_self.ToggleSelectedUser = function (data, event) {
var toggle = !data.IsSelected();
data.IsSelected(toggle);
if(toggle === true)
{
_self.SelectedClient.push(data.ClientName());
}
else
{
_self.SelectedClient.remove(data.ClientName());
}
Why walk on the clients list recursively when you can simply create a SelectedClients field on the View-Model, and remove/add to it upon toggling?
For example:
_self.SelectedClients = ko.observableArray([]);
_self.ToggleSelectedUser = function (data, event) {
var toggle = !data.IsSelected();
data.IsSelected(toggle);
if (toggle)
_self.SelectedClients.push(data.ClientName());
else
_self.SelectedClients.remove(data.ClientName());
};
See Fiddle.
Update:
As per your comment, when you do need to walk recursively on the tree, you can try something like this:
function AggregateSelectedClients(clients, results)
{
results = results || [];
if (!clients || !clients.length) return results;
ko.unwrap(clients).forEach(function(v, i)
{
var selected = ko.unwrap(v.IsSelected);
var subClients = ko.unwrap(v.SubClient);
if (selected)
results.push(ko.unwrap(v.ClientName));
if (subClients && subClients.length)
AggregateSelectedClients(subClients, results);
});
return results;
}
The selected children have to be added to the parent selection.
ko.utils.arrayForEach(item.SubClient(), function (subItem) {
if (subItem.IsSelected()) {
selected.push(subItem.ClientName());
}
//cp.GetSelectedClientsArray(subItem);
selected.push.apply(selected, cp.GetSelectedClientsArray(subItem));
});
See fiddle
I hope it helps.

Testing Angular Filter That Returns An Array with Jasmine

So, I'm having issues testing an angular filter that takes an array that has previously been sorted by a group property. It uses a flag property to indicate that the item is the first observation of that group, and then false for subsequent observations.
I'm doing this to have a category header in the UI with an ng-repeat directive.
When I test the filter, the output does not return the array with the flags unless I create new objects for the return array. This is a problem, because it causes an infinite loop when running in a webpage. The code works in the webpage when it just adds a flag property to the input object.
Is there some additional step I should be taking to simulate how angular handles filters so that it outputs the proper array?
This is what my test looks like right now.
describe('IsDifferentGroup', function() {
var list, itemOne, itemTwo, itemThree;
beforeEach(module("App.Filters"));
beforeEach(function () {
list = [];
itemOne = new ListItem();
itemTwo = new ListItem();
itemThree = new ListItem();
itemOne.group = "A";
itemTwo.group = "B";
itemThree.group = "C";
list.push(itemOne);
list.push(itemOne);
list.push(itemOne);
list.push(itemOne);
list.push(itemTwo);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
});
it('should flag the items true that appear first on the list.', (inject(function (isDifferentGroupFilter) {
expect(list.length).toBe(10);
var result = isDifferentGroupFilter(list);
expect(result[0].isDifferentGroup).toBeTruthy();
expect(result[1].isDifferentGroup).toBeFalsy();
expect(result[4].isDifferentGroup).toBeTruthy();
expect(result[5].isDifferentGroup).toBeTruthy();
expect(result[6].isDifferentGroup).toBeFalsy();
expect(result[9].isDifferentGroup).toBeFalsy();
})));
});
And here is something like the code with the filter:
var IsDifferentGroup = (function () {
function IsDifferentGroup() {
return (function (list) {
var arrayToReturn = [];
var lastGroup = null;
for (var i = 0; i < list.length; i++) {
if (list[i].group != lastGroup) {
list[i].isDifferentGroup = true;
lastAisle = list[i].group;
} else {
list[i].isDifferentGroup = false;
}
arrayToReturn.push(list[i]);
}
return arrayToReturn;
});
}
return IsDifferentGroup;
})();
Thanks!
I figured out my issue.
When I was passing the items into the list, I just pushed a pointer to an item multiple times. I was not passing in unique objects so the flag was being overridden by the following flag in the array(I think). So, I just newed up 10 unique objects using a loop, pushed them into the array and ran it through the filter. And it worked.
I'm not entirely sure my analysis is correct about the override, because itemTwo was not being flagged as unique when it was the only itemTwo in the array. But the test is working as I would expect now so I'm going to stop investigating the issue.

Resources