How to split two items inside a JSON array in angular - javascript

This is my code:
$scope.center_name = [];
$scope.stats = ["Stats"];
$scope.totMemCenterData = [];
var query = "SELECT count(*) as tot_mem, centers.name as center_name FROM mem_groups "
+ "INNER JOIN centers ON mem_groups.center_id=centers.id GROUP BY centers.id";
$cordovaSQLite.execute(db, query, [])
.then(function(res){
if (res.rows.length > 0) {
for (var i=0; i < res.rows.length; i++) {
$scope.totMemCenterData = res.rows.item(i);
console.log(JSON.stringify($scope.totMemCenterData));
}
}
}, function(err){
// $cordovaToast.showShortBottom('Something Went Wrong').then(function(success){}, function(err){});
console.log(err.message);
});
This is the result of console.log(JSON.stringify($scope.totMemCenterData)); :
{"center_name":"AFG - ANONANG","tot_mem":6}
{"center_name":"BAM - BUENAVISTA","tot_mem":3}
{"center_name":"GHT - TAGAS","tot_mem":2}
I want to put all center_names in one array also the tot_mem on another array. I want it to be like:
Centers: "AFG - ANONANG", "BAM - BUENAVISTA", "GHT - TAGAS"
Tot_mem: 6, 3, 2
I'm gonna put those values on a chart. Centers on the x-axis and tot_mem on the y-axis

You can do this,
$scope.center_names = [];
$scope.tot_mem = [];
angular.forEach($scope.sampleTest, function(key, value) {
$scope.center_names.push(key["center_name"]);
$scope.tot_mem.push(key["tot_mem"]);
});
DEMO
var app = angular.module('sampleApp', []);
app.controller('myCtrl', function($scope) {
$scope.sampleTest = [{
"center_name": "AFG - ANONANG",
"tot_mem": 6
}, {
"center_name": "BAM - BUENAVISTA",
"tot_mem": 3
}, {
"center_name": "GHT - TAGAS",
"tot_mem": 2
}];
$scope.center_names = [];
$scope.tot_mem = [];
angular.forEach($scope.sampleTest, function(key, value) {
$scope.center_names.push(key["center_name"]);
$scope.tot_mem.push(key["tot_mem"]);
});
});
<!DOCTYPE html>
<html ng-app="sampleApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>
</head>
<body ng-controller="myCtrl">
<h1> Center names </h1>
<div ng-repeat="item in center_names">
{{item}}
</div>
<h1> Total memory </h1>
<div ng-repeat="tot in tot_mem">
{{tot}}
</div>
</body>
</html>

Some Observations :
TypeError: res.rows.item is not a function
So, use this res.rows.item[i] instead of res.rows.item(i).
Why JSON.stringify ? As you have to iterate each object to create two different arrays based on the keys. So, leave $scope.totMemCenterData as it is.
Instead of checking the length of res.rows.length check the length of items(res.rows.item.length) as you are going to iterate items.
Working demo :
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',function($scope) {
var res = {
"rows": {
"item": [{
"center_name": "AFG - ANONANG",
"tot_mem": 6
}, {
"center_name": "BAM - BUENAVISTA",
"tot_mem": 3
}, {
"center_name": "GHT - TAGAS",
"tot_mem": 2
}]
}
};
$scope.center_names = [];
$scope.tot_mem = [];
for (var i=0; i < res.rows.item.length; i++) {
$scope.totMemCenterData = res.rows.item[i];
$scope.center_names.push($scope.totMemCenterData.center_name);
$scope.tot_mem.push($scope.totMemCenterData.tot_mem);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<b>Center Names :</b>
<div ng-repeat="names in center_names">
{{names}}
</div>
<b>Total Mem :</b>
<div ng-repeat="item in tot_mem">
{{item}}
</div>
</div>

Related

Using the join method with an object of arrays to separate with a comma

I have an object made up of an array which contains several objects. I am trying to use the join method but of course, I realised this is only available on arrays unless converted otherwise?
I want to separate the objects I need with a comma/pipe. The outcome should be as follows:
DISOVER | EXPERIENCE | 195 LUXURY
but need some guidance on how to achieve this since I'm getting the following error:
"message": "Uncaught TypeError: data.slideHeading1.join is not a
function"
Is there an alternative way to do this? Please see my code below:
var imgObj = {
"slideData": [{
"slideHeading1": "DISCOVER",
}, {
"slideHeading1": "EXPERIENCE",
}, {
"slideHeading1": "195 LUXURY",
}]
};
imgObj.slideData.forEach(function(data, idx) {
var heading1 = data.slideHeading1.join('|');
var heading2 = data.slideHeading2.join('|');
var heading3 = data.slideHeading3.join('|');
$('.slideTitle .heading-1').append(heading1);
$('.slideTitle .heading-2').append(heading2);
$('.slideTitle .heading-3').append(heading3);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2 class="slideTitle">
<span class="heading-1"></span>
<span class="heading-2"></span>
<span class="heading-3"></span>
</h2>
Edit: Please see the following code which adds more objects to the array: Also - I am using a text rotator which explains why the text is separated by a pipe.
Outcome should be:
<span class="heading-1">DISCOVER | EXPERIENCE | 195 LUXURY</span>
<span class="heading-2">MORE | IT ALL | SUPERJETS</span>
<span class="heading-3">FUEL | | TODAY</span>
Code example:
var imgObj = {
"slideData": [{
"slideHeading1": "DISCOVER",
"slideHeading2": "MORE",
"slideHeading3": "FUEL",
}, {
"slideHeading1": "EXPERIENCE",
"slideHeading2": "IT ALL",
}, {
"slideHeading1": "195 LUXURY",
"slideHeading2": "SUPERJETS",
"slideHeading3": "TODAY",
}]
};
var heading1 = [];
imgObj.slideData.forEach(function(data, idx) {
if (idx < imgObj.slideData.length - 1)
heading1[idx] = data.slideHeading1 + ' | ';
else // skip if the item is the last item
heading1[idx] = data.slideHeading1;
});
document.querySelectorAll('span[class^=heading-]').forEach(function(el, i) {
el.textContent = heading1[i]
});
$(".slideTitle span").Morphext({
animation: "fadeInLeft",
separator: "|",
speed: 4000,
complete: function() {
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Morphext/2.4.4/morphext.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Morphext/2.4.4/morphext.min.js"></script>
<h2 class="slideTitle">
<span class="heading-1"></span>
<span class="heading-2"></span>
<span class="heading-3"></span>
</h2>
Error you are getting because data.slideHeading1 is not array but actual string value
Also Change pipe(|) to comma(,)
I want to separate the objects I need with a comma
Just Change
imgObj.slideData.forEach(function(data, idx) {
var heading1 = data.slideHeading1.join('|');
var heading2 = data.slideHeading2.join('|');
var heading3 = data.slideHeading3.join('|');
$('.slideTitle .heading-1').append(heading1);
$('.slideTitle .heading-2').append(heading2);
$('.slideTitle .heading-3').append(heading3);
});
to this
imgObj.slideData.forEach(function(data, idx) {
var seperator = (idx==imgObj.slideData.length-1)? "":",";
$('.slideTitle .heading-'+( idx+1)).append(data.slideHeading1 + seperator);
});
var imgObj = {
"slideData": [{
"slideHeading1": "DISCOVER",
}, {
"slideHeading1": "EXPERIENCE",
}, {
"slideHeading1": "195 LUXURY",
}]
};
imgObj.slideData.forEach(function(data, idx) {
var seperator = (idx==imgObj.slideData.length-1)? "":",";
$('.slideTitle .heading-'+( idx+1)).append(data.slideHeading1 + seperator);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2 class="slideTitle">
<span class="heading-1"></span>
<span class="heading-2"></span>
<span class="heading-3"></span>
</h2>
You are getting the error because data.slideHeading1 is not an array and join() is a method implemented on array.
I think you want to separate all items by pipe (|). If so, just add that character to the end of the text. Then loop through all the span element to fill with the text from the previously generated array. Something like the following:
var imgObj = {
"slideData": [{
"slideHeading1": "DISCOVER",
}, {
"slideHeading1": "EXPERIENCE",
}, {
"slideHeading1": "195 LUXURY",
}]
};
var heading1 = [];
imgObj.slideData.forEach(function(data, idx) {
if(idx < imgObj.slideData.length - 1)
heading1[idx] = data.slideHeading1 + ' | ';
else // skip if the item is the last item
heading1[idx] = data.slideHeading1;
});
document.querySelectorAll('span[class^=heading-]').forEach(function(el, i){
el.textContent = heading1[i]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2 class="slideTitle">
<span class="heading-1"></span>
<span class="heading-2"></span>
<span class="heading-3"></span>
</h2>
Please Note: Since it is little bit confusing between the code you have approched and the text about what you are asking:
I want to separate the objects I need with a comma
Simply replace
heading1[idx] = data.slideHeading1 + ' | ';
With
heading1[idx] = data.slideHeading1 + ', ';

Limit number of links to show in custom paging

Now with my code i see all pages, but i want to limit the number of links.
If i have 10 pages, but i want to see only five:
1 2 3 4 5,
5 6 7 8 9.
How can i do that? This is plunk demo on part of my code
This is my controller:
var booksController = function () {
function all(context) {
var size = 2,
page = +context.params['page'] || 0;
templates.get('books')
.then(function (template) {
var booksRef = firebase.database().ref('books');
booksRef = booksRef.orderByChild('timestamp');
booksRef.on('value', function (snapshot) {
this.data = [];
snapshot.forEach(function (child) {
this.data.push(child.val());
}.bind(this));
var pagesLen = Math.ceil(data.length / size),
pages = [];
for (var i = 0; i < pagesLen; i+= 1) {
pages.push({
page: i,
displayPage: i + 1
});
}
data = data.slice(page * size, (page + 1) * size);
context.$element().html(template({
books: data,
pages: pages
}));
});
});
}
return { all: all };
}();
And my hadlebars template:
<section id="primary-content">
<div class="wrapper">
<h1 class="above">Books: </h1>
{{#each books}}
<h1>{{title}}</h1>
{{/each}}
<div id="medium">
</div> {{!--end medium--}}
<ul class="pagination">
{{#pages}}
<li>
<a class="btn btn-sm btn-default" href="#/books/{{page}}">{{displayPage}}</a>
</li>
{{/pages}}
</ul>
</div>

How to remove the filter on only the clicked item in ng-repeat?

In my application, I am masking the serial numbers by default (using a custom filter in angular). When the user clicks on 1 particular masked serial number, the mask needs to be removed.
Here is my code so far:
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', [ '$scope', function($scope){
$scope.name = 'Superhero';
$scope.serialNumbers = [
{serial: 12345678},
{serial: 22245678},
{serial: 33345678},
];
}]);
myApp.filter('mask', function() {
return function(input) {
var inputArray = input.toString().split('');
for (var i = 2, l = inputArray.length; i < l - 2; i++) {
inputArray[i] = '*'; // replace
}
return inputArray.join('');
};
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app='myApp'>
<div ng-controller="MyCtrl">
Hello, {{name}}!
<p>Below are your serial numbers:</p>
<p ng-repeat="serialNumber in serialNumbers">{{serialNumber.serial | mask}}</p>
</div>
</body>
</html>
How do I achieve this?
Not totally sure I understand issue but you can use an argument in the filter and for simplicity bind it to a property of the object
myApp.filter('mask', function() {
return function(input, noMask) {
if(noMask){
return input;
}
var inputArray = input.toString().split('');
for (var i = 2, l = inputArray.length; i < l - 2; i++) {
inputArray[i] = '*'; // replace
}
return inputArray.join('');
};
});
Then in html do something like:
<p ng-repeat="serialNumber in serialNumbers"
ng-click="serialNumber.noMask=!serialNumber.noMask">
{{serialNumber.serial | mask: serialNumber.noMask }}
</p>

javaScript - Add key & value to Object

There is a forEach in my function for create Object:
Please Run code snippet:
angular.module('myApp', []).controller('myCntl', function($scope) {
$scope.t = '';
var input = "a,b,c,d,e,r \n1,1,1,1,1,1\n2,2,2,2,2,1 \n3,3,3,3,3,1";
var rows = input.split('\n');
var result = {
header: [],
body: []
};
//Get Header
var headerString = rows[0].split(',');
headerString.forEach(function(val) {
result.header.push(val);
});
rows.splice(0, 1);
rows.splice(rows.length - 1, rows.length); //delete "" row, from end array
// Get Body 'a,b,c,d,...'
rows.forEach(function(val, i) {
var bodyString = val.split(',');
var objBody = new Object;
bodyString.forEach(function(val, i) {
var strHeader = result.header[i];
objBody[strHeader] = val;
});
result.body.push(objBody);
});
$scope.result = result.body;
$scope.show = function() {
console.log($scope.result)
$scope.t = $scope.result;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" ng-app="myApp" ng-controller="myCntl">
<button ng-click="show()">click me</button>
<span ng-repeat="item in t">
{{item}}
</span>
</div>
And, this is objBody after forEach:
objBody = {
a: "1",
b: "1",
"c": "1"
}
Now, my problem is in key with double qoutation in last record of objBody.
What is it? and Why?! > ("c")
The problem was arising due to the white space between r and \n in the input string. When you split the string by \n, the rows[0] will be "a,b,c,d,e,r ". And after you split it with comma, then the last element will contain the white space like this "r ".
So just change the following line of code
var input = "a,b,c,d,e,r \n1,1,1,1,1,1\n2,2,2,2,2,1 \n3,3,3,3,3,1";
to
var input = "a,b,c,d,e,r\n1,1,1,1,1,1\n2,2,2,2,2,1\n3,3,3,3,3,1";
to fix the issue.
angular.module('myApp', []).controller('myCntl', function($scope) {
$scope.t = '';
var input = "a,b,c,d,e,r \n1,1,1,1,1,1 \n2,2,2,2,2,1 \n3,3,3,3,3,1";
input = input.replace(" ","");
console.log(input);
var rows = input.split('\n');
var result = {
header: [],
body: []
};
//Get Header
var headerString = rows[0].split(',');
headerString.forEach(function(val) {
result.header.push(val);
});
rows.splice(0, 1);
rows.splice(rows.length - 1, rows.length); //delete "" row, from end array
// Get Body 'a,b,c,d,...'
rows.forEach(function(val, i) {
var bodyString = val.split(',');
var objBody = new Object;
bodyString.forEach(function(val, i) {
var strHeader = result.header[i];
objBody[strHeader] = val;
});
result.body.push(objBody);
});
$scope.result = result.body;
$scope.show = function() {
console.log($scope.result)
$scope.t = $scope.result;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" ng-app="myApp" ng-controller="myCntl">
<button ng-click="show()">click me</button>
<span ng-repeat="item in t">
{{item}}
</span>
</div>
EDIT: You have found some answer. But my way for removing white spaces from the dynamic input string would be
input = input.replace(" ","");
I solved problem with split by regexExp:
var myRegex = new RegExp(/\s*\n/);
var rows = input.split(myRegex);
This command split every ' \n' in string. This work for me.

Limit checkbox selections and bind to an array in AngularJS

I am trying to achieve two things:
Bind an array to a list of checkboxes (just a string array), and
Limit the number of selections the user can make to a number between
1 and the number of available items less 1.
I can get (2) to work until the user clicks the last item, at which point it loses track and the items remain selected.
The interactive code is up here: http://codepen.io/adamcodegarden/pen/bdbQqe (forked from a similar example)
My HTML/Angular code:
<p ng-repeat="item in allOptions" class="item" id="{{item}}">
{{item}} <input type="checkbox" ng-change="sync(bool, item)" ng-model="bool" ng-checked="isChecked(item)"> Click this to sync this item with the target array. {{item}} Selected: {{bool}}
and the JS:
var myApp = angular.module("myApp", []);
var maxItems = 1;
myApp.controller('myController', function($scope) {
$scope.isChecked = function(item){
var match = false;
for(var i=0 ; i < $scope.data.length; i++) {
if($scope.data[i] === item) {
match = true;
}
}
return match;
};
$scope.allOptions = [
'one', 'two', 'three', 'four'
];
$scope.data = [
];
$scope.sync = function(bool, item){
if (bool) {
// add item
$scope.data.push(item);
// if we have gone over maxItems:
if ($scope.data.length > maxItems) {
//remove oldest item
$scope.data.splice(0,1);
}
} else {
// remove item
for (var i=0 ; i < $scope.data.length; i++) {
if ($scope.data[i] === item){
$scope.data.splice(i,1);
}
}
}
};
});
I like plunker more than codepen. So I created this plunker
http://plnkr.co/edit/l8gxQHXBQdFeKIuwf3f0?p=preview
The main idea is that I format the original array as:
$scope.allOptions = [
{key: 'one'}, {key: 'two'}, {key: 'three'}, {key:'four'}
];
And slight change to the sync logic as well:
$scope.sync = function(bool, item){
if (bool) {
// add item
$scope.data.push(item);
// if we have gone over maxItems:
if ($scope.data.length > maxItems) {
//remove first item
$scope.data[0].checked = false;
$scope.data.splice(0,1);
}
} else {
// remove item
for (var i=0 ; i < $scope.data.length; i++) {
if ($scope.data[i] === item) {
$scope.data.splice(i,1);
}
}
}
};
Also change html portion:
<p ng-repeat="item in allOptions" class="item" id="{{item.key}}">
{{item.key}} <input type="checkbox" ng-change="sync(item.checked, item)" ng-model="item.checked"> Click this to sync this item with the target array. {{item.key}} Selected: {{bool}}

Categories

Resources