Unable to bind data to dropdown-multiselect in angularjs - javascript

Please check the plunker. I'm not able to bind the data which come from server like this(["Monday","Tuesday"]).
I know data binds when it is like
$scope.selectedUser = [{ id: 2, name: 'Monday' },
{id: 3,name:'Tuesday'}];.
I want to make ["Monday","Tuesday"] to [{ id: 2, name: 'Monday' },{id: 3,name:'Tuesday'}] in javascript so that it would bind in dropdown.
Please help me solve this issue.
demo plunker

//This is the ng filter to create id as you get the data from server
app.filter('createId',function(){
return function(arr){
var result = [];
for(var i = 0;i < arr.length;i++){
var id = arr[i].substring(0,3);
var obj = {'id':id,'name':arr[i]};
result.push(obj);
}
return result;
}
});
//In js controller you can costomize your array of user by using ng-filter like this
$scope.users = $filter('createId')($scope.users);
//This is because index will be changed every time so this can't be used as ID
$scope.selectedUser = $filter('createId')($scope.selectedUser);

Achieve your json using below code
var temp = ["Monday", "Tuesday"]
var result = "[";
for (var i = 0; i < temp.length; i++) {
if(i!=temp.length-1)
{
result += "{id:'" + i + "',name:'" + temp[i] + "'},";
}
else
{
result += "{id:'" + i + "',name:'" + temp[i] + "'}";
}
alert(result);
}
console.log(result+"]")

You can do this
$scope.selectedUsers=[];
//serverData is data from server
for(var i =0 ; i < serverData.length ; i++){
$scope.selectedUsers.push({id:i , name: serverData[i]})
}
And in your angular
$scope.doSelectedUser = function () {
$scope.selectedUser = $scope.selectedUsers;
}

$scope.selectedUser should have a reference to the actual objects in $scope.users. for example, this is what i had to change in your plunker to bind it with the users match the user names list:
var defaultSelectedUsers = ["Sunday","Tuesday"];
$scope.users = [
{ id: 1, name: 'Sunday' },
{ id: 2, name: 'Monday' },
{ id: 3, name: 'Tuesday' } ];
$scope.selectedUser = $scope.users.filter(function(user){
return defaultSelectedUsers.indexOf(user.name) != -1;
});
Online Demo - http://plnkr.co/edit/3TOkZEaZVSxtpNbFaNkg?p=preview
You mentioned you want to do it from your server's response. it's unclear how you want to decide which one to select, assuming you rely on a default selected users by name according your example.
This is how you handle a server's response and modify the new selected users:
var defaultSelectedUsers = ["Sunday","Tuesday"];
$http.get('/api/v1/users')
.success(function(users)){
$scope.users = users;
$scope.selectedUser = users.filter(function(user){
return defaultSelectedUsers.indexOf(user.name) != -1;
});
});
You may change the filter condition to what makes sense for you

Related

Count duplicate property values of a nested Javascript object

I'm feeding in information in from an API with the format -
Records = { 0: {fields: {name: "nameExample" place: "placeExample"} }
{1: {fields: {name: "nameExample" place: "placeExample"} }
etc etc
I'm looking for a way to count duplicates of the 'place' field in the format: Scotland(4), London(6) etc. where the number is the amount of times it repeats.
The closest I've got as of yet is counting the letters in each place name, but I'm not sure what I'm doing wrong. I think if I can get them in the same array then it would be simple, but when I tried to do that it put each place in a different array.
Also must be vanilla javaScript, no jQuery. Many thanks!
var URL = new Array();
URL[0] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45";
URL[1] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45&offset=45";
URL[2] = "https://www.vam.ac.uk/api/json/museumobject/search?q=a&limit=45&offset=90";
var nRequest = new Array();
for (var i=0; i<3; i++){
(function(i) {
nRequest[i] = new XMLHttpRequest();
nRequest[i].open("GET", URL[i], true);
nRequest[i].onreadystatechange = function (oEvent) {
if (nRequest[i].readyState === 4) {
if (nRequest[i].status === 200) {
var data = JSON.parse(nRequest[i].responseText);
var url = 'http://media.vam.ac.uk/media/thira/collection_images/';
for (let key in data.records) {
let value = data.records[key];
let image = value.fields.primary_image_id;
let res = image.substr(0, 6);
document.querySelector(".map").innerHTML += '<div class="' + value.fields.place + ' map"> ' + value.fields.place + ' <br> </div>';
}
} else {
console.log("Error", nRequest[i].statusText);
}
}
//
};
nRequest[i].send(null);
})(i);
};
If thats the data structure you can solve it like so:
const Records = [
{fields: {name: "nameExample", place: "placeExample"}},
{fields: {name: "nameExample", place: "placeExample"}}
];
const result = Records.reduce((acc, {fields}) => {
if(acc[fields.place]) acc[fields.place]++;
else acc[fields.place] = 1;
return acc;
}, {})
console.log(result);
You can use the reduce function to convert the array data.records to an object with the place as key and number of occurrences as value.
data.records.reduce((accum, currVal) => {
if (!(currVal.fields.place in accum)){
accum[currVal.fields.place] = 0;
}
accum[currVal.fields.place] += 1;
return accum;
}, {});

How can find the sum and count of json data in javascript

Hi iam trying to group my json data in to sub json data.
here is my json data
[
{
"STATUS":"ACTIVE",
"AMOUNT":200,
"pENDING":100,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":100,
"pENDING":30,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":150,
"pENDING":10,
}
]
and my expected result like
[
{
"STATUS":"ACTIVE",
"COUNT":"1",
"TOTAL AMOUNT":200,
"TOTAL PENDING":100
},
{
"STATUS":"NOTACTIVE",
"COUNT":"2",
"TOTAL AMOUNT":250,
"TOTAL PENDING":40
}
]
I want the separate count ,sum of amount,sum of pending for each status
Could you please help me to find the result
You can do it like this
Idea to handle such things.
so here i am looping through the array and checking for status in the output object. if the status is already in output object i will update the required values. if it's not there than i will create a new one in output object.
let arr =[
{
"STATUS":"ACTIVE",
"AMOUNT":200,
"PENDING":100,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":100,
"PENDING":30,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":150,
"PENDING":10,
}
];
let output = arr.reduce((op,cur)=>{
if(op[cur['STATUS']]){
op[cur['STATUS']]['TOTAL_AMOUNT']+=cur['AMOUNT'];
op[cur['STATUS']]['TOTAL_PENDING']+=cur['PENDING'];
op[cur['STATUS']]['COUNT']++;
} else {
op[cur['STATUS']] ={
'COUNT' : 1,
'TOTAL_AMOUNT' : cur['AMOUNT'],
'TOTAL_PENDING' : cur['PENDING'],
}
}
return op;
},{})
console.log(output);
Trying to fix your own method I would suggest something like this. I tried to do it generic in case you would find it more useful, although this solution would have a problem if the AMOUNT or PENDING entries are not numeric.
const IDENTIFIER = 'STATUS'
const result= {};
data.forEach( entry => {
// Check is this status exists, if not, create one
if(!result[entry[IDENTIFIER]]){
result[entry[IDENTIFIER]] = {}
}
// For each item in the entry add the value
Object.keys(entry).forEach( item => {
// Only sum the items that are not the identifier
if(item !== IDENTIFIER){
result[entry[IDENTIFIER]][item] = (result[entry[IDENTIFIER]][item] || 0) + entry[item];
}
})
});
Hope you find this useful
Try this my friend!
var json = [{
"STATUS":"ACTIVE",
"AMOUNT":200,
"pENDING":100,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":100,
"pENDING":30,
},
{
"STATUS":"NOTACTIVE",
"AMOUNT":150,
"pENDING":10,
}];
var result = [];
var totalActive = 0;
var amountActive = 0;
var pendingActive = 0;
var totalNotActive = 0;
var pendingNotActive= 0;
var amountNotActive = 0;
for(var i=0; i < json.length; i++){
var item = json[i];
if (item.STATUS.toString() == "ACTIVE"){
totalActive +=1;
amountActive = amountActive + item.AMOUNT;
pendingActive = pendingActive + item.pENDING;
}
else
{
totalNotActive +=1;
amountNotActive = amountNotActive + item.AMOUNT;
pendingNotActive = pendingNotActive + item.pENDING;
}
}
result.push({ "STATUS" : "ACTIVE" , "COUNT" : totalActive.toString(), "AMOUNT" : amountActive.toString(), "pENDING" : pendingActive.toString() })
result.push({ "STATUS" : "NOTACTIVE" , "COUNT" : totalNotActive.toString(), "AMOUNT" : amountNotActive.toString(), "pENDING" : pendingNotActive.toString() })
console.log(result);

Underscore Equivalent to Javascript For Loop?

I'd like to convert this code:
for (var i = 0; i < product.ages.length; i ++){
for (var j = 0; j < $scope.ages.length; j ++){
if (product.ages[i].id == $scope.ages[j].id){
$scope.ages[j]['ticked'] = true;
}
}
}
into underscore.js. please help.
Another way to solve this problem would be to first create a hash of the scope.ages using underscore's indexBy:
var scope_ages = _.indexBy($scope.ages, 'id');
The object would look something like:
{
1: ref to scope.ages with id 1,
2: ref to scope.ages with id 2,
etc.
}
Then iterate over the product ages using each to set the ticked value:
_.each(product.ages, age => scope_ages[age.id].ticked = true)
var product = {
ages: [
{ id : 1 }
]
}
var $scope = {
ages: [
{ id : 0, ticked: false },
{ id : 1, ticked: false },
{ id : 2, ticked: false },
]
}
var scope_ages = _.indexBy($scope.ages, 'id');
_.each(product.ages, age => scope_ages[age.id].ticked = true)
document.getElementById('scope_ages').textContent = JSON.stringify(scope_ages);
document.getElementById('result').textContent = JSON.stringify($scope.ages);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore.js"></script>
<h1>scope_ages</h1>
<p>
<pre id="scope_ages"></pre>
</p>
<h1>Scope</h1>
<p>
<pre id="result"></pre>
</p>
This would be your code in underscore:
_.each(product.ages, function(pAge) {
_.each($scope.ages, function(sAge) {
if (pAge.id === sAge.id) {
sAge.ticked = true;
}
});
});
Here is an example on how you do an _.each on an object.
var example = {"hello":"world", "this":"is", "super":"neat"};
_.each(example, function(value, index){
console.log(index + ":" + value);
}
->hello:world
->this:is
->super:neat
You can use _.find
_.each($scope.ages, function(v){
v.ticked = _.find(product.ages, function(a){
return v.age === a.age;
})?true:false;
})
Also, just a pointer, you should use break on match.

How to find duplicated title values in a map

I'm new to Javascript, come from Java, this is less intuitive for me.
I would like to check for duplication of the title value and concatenate to the duplicated title the producer name
My idea is to sort the values and then check each one with is next for duplication
Can you suggest me how to implement this kind of solution?
function getItems(itemKeys, itemSortOrders, itemsMap)
{
var items = _.map(itemKeys, function(itemKey, index) {
var item = itemsMap[itemKey];
return _.extend({
key: itemKey,
title: item.title,
imageURL: item.imageURL,
formattedPrice: utils.formatMoney(item.price),
producerKey: item.producerKey,
producerTitle: item.producerTitle,
allowOrder: true,
sortOrder: itemSortOrders[index]
}, calculateItemDetails(item.deliveryDayAvailable, item.deliveryDayStatus, item.deliveryDayUsageCount));
});
items = _.compact(items);
return items;
}
Thanks
You can test if item have duplicates with this function, it use filter to find the same items and check if the length is larger then 1.
function haveDuplicates(itemKeys, itemsMap, itemKey) {
var item = itemsMap[itemKey];
var dups = itemKeys.filter(function(key) {
return itemsMap[key] == item;
});
return dups.length > 1;
}
var itemsMap = {
'foo': 'Lorem',
'bar': 'Lorem',
'baz': 'Ipsum',
'quux': 'Dolor'
};
var output = document.getElementById('output');
var itemKeys = Object.keys(itemsMap);
itemKeys.map(function(key) {
output.innerHTML += itemsMap[key] + ' ' +
(haveDuplicates(itemKeys, itemsMap, key) ? 'have' : 'don\'t have') + '\n';
});
<pre id="output"></pre>
SO this is what i did eventually and this worked
var duplicateMap = {};
_.each(itemsMap, function(item) {
var title = item.title.trim();
if (duplicateMap[title]) {
duplicateMap[title] = 2;
}
else {
duplicateMap[title] = 1;
}
});

Count times a value is repeated in data fetched using REST call

I'm fetching data from SharePoint using REST, and everything works just fine, except that I would like to count the times the same item appears.
This is the jQuery:
var url = "https:xxxxxxxx/_vti_bin/ListData.svc/RMSD_Tasks?$orderby=TypeOfIssueValue asc,StatusValue desc&$filter=StatusValue ne 'Completed'&groupby=TypeOfIssueValue/StatusValue";
var lastIssue = '';
$.getJSON(url, function (data) {
$('#totalCounter').text(data.d.results.length);
for (var i = 0; i < data.d.results.length; i++) {
var dateReceived = data.d.results[i].DateReceived;
dateReceived = new Date(parseInt(dateReceived.replace("/Date(", "").replace(")/", ""), 10)).toLocaleString('en-US', {
year: 'numeric',
month: 'numeric',
day: '2-digit'
});
var issue = data.d.results[i].TypeOfIssueValue;
console.log(data.d.results[i].TypeOfIssueValue);
if (issue != lastIssue) {
lastIssue = issue;
$('#myDataList').append('' + issue + '<span class="badge">' + issue.length + '</span>');
}
}
});
I need to count how many time a specific TypeOfIssueValue appears. When I see the console it shows exactly what I would like to add to me info:
I just added a issue.length in the badge were I want to insert the number for the sake of just having something there, but I know it won't show what I want. Thanks!
var data = {
d: {
results: [
{ TypeOfIssueValue: '456' },
{ TypeOfIssueValue: '123' },
{ TypeOfIssueValue: '789' },
{ TypeOfIssueValue: '123' }
]
}
};
var filteredItems = data.d.results.filter(function(item){
return item.TypeOfIssueValue == '123';
});
var count = filteredItems.length;
document.getElementById("output").innerHTML = "Number of items with value '123': " + count;
<div id="output"/>
You could first map the TypeOfIssueValue values to a new array and then count each occurence based on this answer.
The code would be :
var a = data.d.results.map(function(issue) {
return issue.TypeOfIssueValue
});
result = {};
for (i = 0; i < a.length; ++i) {
if (!result[a[i]])
result[a[i]] = 0;
++result[a[i]];
}
The result will be an object with property being type of issue and value being the count of each.
Let me know if this makes sense.
Thanks #srinivas. I accepted your response, although I made some modifications, just in case they are useful to someone else.
I added a class to the span badge and added a new array to push the issues:
issuesArray.push(data.d.results[i].TypeOfIssueValue);
$('#myDataList').append('' + issue + '<span class="badge badgeSpan"></span>');
Then I addded a done() to run after the getJSON:
.done(
function(){ var resultado = foo(issuesArray)[1];
console.log(resultado);
var badges = $('.badgeSpan');
for (var j = 0; j < resultado.length; j++){
badges[j].innerHTML = resultado[j];
}
});
Last I made a small modificfation to the function foo() that you provided:
testArray = [];
function foo(arr) {
var a = [], b = [], prev;
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
testArray.push(a,b)
return testArray;
}
This maybe a very unorthodox solution, but it worked for me. Thanks again.

Categories

Resources