Javascript array.push() do not add but replace it - javascript

I have some checkboxes styled with bootstrapSwitch.
I wrote a script that have to add value of checkbox to an array when bootstrapSwitch state is true.
This is my code :
$('input[name^=skill]').on('switchChange.bootstrapSwitch', function (event, state) {
//alert(state);
//var s = [];
var s = new Array();
if( state === true )
{
//var value = $(this).val();
s.push( $(this).val() );
console.log(s);//(value)
}
console.log(s);//(value)
});
But surprisingly push method replace the value and my s array always have one index.
Would you please let me know why is that?
Thanks in Advance

var s = new Array();
Define this out of the handler function.
It's always 1 because you're recreating it everytime.

var s = new Array();// this line should be out side of function. so it will not be new object everytime
so try this
var s = new Array();// this line should be here. so it will not be new object everytime
$('input[name^=skill]').on('switchChange.bootstrapSwitch', function (event, state) {
//alert(state);
//var s = [];
var s = new Array();
if( state === true )
{
//var value = $(this).val();
s.push( $(this).val() );
console.log(s);//(value)
}
console.log(s);//(value)
});

var s = [];
$('input[name^=skill]').on('switchChange.bootstrapSwitch', function (event, state) {
//alert(state);
//var s = [];
if( state === true )
{
//var value = $(this).val();
s.push( $(this).val() );
console.log(s);//(value)
}
console.log(s);//(value)
});
Just declare the array outside. User [] instead on new Array() as it is faster.

Related

For loop not working with js map function

I am trying to print array in html, but my for loop is not working. I am trying to get the length of dataArrayNew but its not returning back where my for loop is added. If i console.log(dataArrayNew.title); , I am able to see the correct result. I am also attaching the print screen of my browser console.
var dataArrayNew = [];
function fetch_section_data_1(){
var keys = Object.keys(localStorage).filter(function(key) {
return /^section\d+$/.test(key);
});
var dataArray = keys.map(function(key) {
dataArrayNew = JSON.parse(localStorage.getItem(key));
console.log(dataArrayNew.title);
//lengtharray = dataArrayNew.length;
//console.log(lengtharray);
//return JSON.parse(localStorage.getItem(key));
});
var $table = $( "<table></table>" );
for(i=0;i<dataArrayNew.length;i++){
var array_no = dataArrayNew[i];
var $line = $( "<tr></tr>" );
$line.append( $( "<td></td>" ).html( array_no.title ) );
$table.append( $line );
console.log(dataArrayNew.title);
}
$table.appendTo(document.body);
}
The reason why you cannot see the length property is because you are reassigning dataArrayNew from an array to a result JSON.parse which is an object, and objects do not have the property length. Instead of reassigning the value of dataArrayNew, why don't you push the value of JSON.parse(localStorage.getItem(key)) to it, like so:
dataArrayNew.push(JSON.parse(localStorage.getItem(key)));
So your code should look something like this:
var dataArrayNew = [];
function fetch_section_data_1(){
var keys = Object.keys(localStorage).filter(function(key) {
return /^section\d+$/.test(key);
});
var dataArray = keys.map(function(key) {
var currIn = JSON.parse(localStorage.getItem(key));
console.log(currIn);
// push data to dataArrayNew
dataArrayNew.push(currIn);
//lengtharray = dataArrayNew.length;
//console.log(lengtharray);
//return JSON.parse(localStorage.getItem(key));
});
var $table = $( "<table></table>" );
// You should be able to get the length here now
for(var i = 0; i < dataArrayNew.length; i++){
var array_no = dataArrayNew[i];
var $line = $( "<tr></tr>" );
$line.append( $( "<td></td>" ).html( array_no.title ) );
$table.append( $line );
console.log(dataArrayNew.title);
}
$table.appendTo(document.body);
}

Return variable inside .forEach()

How can I access the scope inside foreach to grab the variable value ?
var fruitCollection = ['Grape','Orange','Banana'];
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
return fruitRecipe;
});
}
fruitsNeeded(); // undefined
EDIT Expected output:
// grape.txt
// orange.txt
// banana.txt
You cannot return the value from forEach function
forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable.
You could use map function for it
var fruitCollection = ['Grape','Orange','Banana'];
var fruitsNeeded = function(){
return fruitCollection.map(function(fruit) {
return fruit.toLowerCase() + '.txt';
});
}
ES6 snippet:
var fruitCollection = ['Grape','Orange','Banana'];
var fruitsNeeded = () => fruitCollection.map(f => f.toLowerCase() + '.txt');
document.write(JSON.stringify(fruitsNeeded()));
Another option is to build an array and return the whole array:
var fruitCollection = ['Grape','Orange','Banana'];
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
var fruitRecipeList = [];
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
fruitRecipeList.push(fruitRecipe);
});
return fruitRecipeList;
}
fruitsNeeded();
forEach has no return value; it is simply a way to execute over an array. You probably want map:
var fruits = fruitCollection.map(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
return fruitRecipe;
});
// fruits = ['grape.txt','orange.txt','banana.txt']
Rather then returning a value from the forEach, you can add them to another global scope variable.
Like this:
var fruitCollection = ['Grape','Orange','Banana'];
var fruitFiles = [] ;
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
fruitFiles.push(fruitRecipe) ;
});
return fruitFiles ;
}
fruitsNeeded(); // ["grape.txt", "orange.txt", "banana.txt"]
I hope this helps,Jacob

Trying to push multiple values into array ( Isotope )

I'm using Isotope to function as a categorical organizer of linked content in a fancy layout. I'm trying to push multiple values into an array so it'll display all items touched by the filters. The end result is, however, just displaying the latest item in the array instead of the sum total. Initially, I was pushing all my values into a string, then declaring x as the final result-- I realize this isn't the way to go about this, and have since modified it. Instead of a string, I'm pushing into an array, and hoping to join each value so they'll all be displayed. However, I'm still getting nothing more than the latest selected value. JS as it stands below.
// store filter for each group
var filters = {};
$('.filters').on('click', '.button', function() {
var filters = [];
// var filters = '';
var selected = $(this).data('selected');
var group = $(this).data('group');
var currentFilter = $(this).data('filter');
// toggle function along with having multiple selectors
if(selected == "0") {
filters.push($(this).data('filter'));
filters = filters.join(', ');
// filters = $(this).data('filter');
$(this).data('selected', "1");
$(this).addClass('is-checked')
}
else {
$(this).data('selected', "0");
$(this).removeClass('is-checked')
}
// set filter for Isotope
$grid.isotope({
filter: filters
});
// flatten object by concatting values
function concatValues(obj) {
var value = '';
for (var prop in obj) {
value += obj[prop];
}
return value;
}
});
}());
I've also set up a codepen for fiddling. Thanks for any suggestions that come. Even pointing me to documentation or tutorials I may have missed would be a great help. For now, I'm studying this jsfiddle that does what I'm shooting for, to see how I can modify my code to better suit what's going on here.
Last week I also spend crazy time with this. :) Luckly I found Desandro's codepen http://codepen.io/desandro/pen/owAyG/
Hope that helps.
$( function() {
// filter functions
var filterFns = {
greaterThan50: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) > 50;
},
even: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) % 2 === 0;
}
};
// init Isotope
var $container = $('.isotope').isotope({
itemSelector: '.color-shape',
filter: function() {
var isMatched = true;
var $this = $(this);
for ( var prop in filters ) {
var filter = filters[ prop ];
// use function if it matches
filter = filterFns[ filter ] || filter;
// test each filter
if ( filter ) {
isMatched = isMatched && $(this).is( filter );
}
// break if not matched
if ( !isMatched ) {
break;
}
}
return isMatched;
}
});
// store filter for each group
var filters = {};
$('#filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[ filterGroup ] = $this.attr('data-filter');
// arrange, and use filter fn
$container.isotope('arrange');
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
This is the solution I ended up with.
I came up with a separate solution but this is a great pen. I wish I had seen it before.
$(document).ready(function() {
// init Isotope
var $grid = $('.grid').isotope({
itemSelector: '.element-item',
layoutMode: 'fitRows',
fitRows: {
gutter: 27
}
});
// store filter for each group
var filters = [];
$('.filters').on('click', '.button', function() {
var filterstring = '';
var selected = $(this).data('selected');
var currentFilter = $(this).data('filter');
// toggle function along with having multiple selectors
if (selected == "0") {
filters.push( currentFilter );
$(this).data('selected', "1");
$(this).addClass('is-checked')
} else {
$(this).data('selected', "0")
$(this).removeClass('is-checked')
var filtername = $(this).data('filter')
var i = filters.indexOf(filtername)
filters.splice(i, 1)
}
filterstring = filters.join(', ');
// set filter for Isotope
$grid.isotope({
filter: filters.join("")
});
});
});

Sorting the results of an indexedDB query

I want to sort results obtained from indexedDB.
Each record has structure {id, text, date} where 'id' is the keyPath.
I want to sort the results by date.
My current code is as below:
var trans = db.transaction(['msgs'], IDBTransaction.READ);
var store = trans.objectStore('msgs');
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound("");
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false){
return;
}
console.log(result.value);
result.continue();
};
Actually you have to index the date field in the msgs objectStore and open an index cursor on the objectStore.
var cursorRequest = store.index('date').openCursor(null, 'next'); // or prev
This will get the sorted result. That is how indexes are supposed to be used.
Here's the more efficient way suggested by Josh.
Supposing you created an index on "date":
// Use the literal "readonly" instead of IDBTransaction.READ, which is deprecated:
var trans = db.transaction(['msgs'], "readonly");
var store = trans.objectStore('msgs');
var index = store.index('date');
// Get everything in the store:
var cursorRequest = index.openCursor();
// It's the same as:
// var cursorRequest = index.openCursor(null, "next");
// Or, if you want a "descendent ordering":
// var cursorRequest = index.openCursor(null, "prev");
// Note that there's no need to define a key range if you want all the objects
var res = new Array();
cursorRequest.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
res.push(cursor.value);
cursor.continue();
}
else {
//print res etc....
}
};
More on cursor direction here: http://www.w3.org/TR/IndexedDB/#cursor-concept
IDBIndex API is here: http://www.w3.org/TR/IndexedDB/#idl-def-IDBIndex
Thanks to zomg, hughfdjackson of javascript irc, I sorted the final array. Modified code as below:
var trans = db.transaction(['msgs'], IDBTransaction.READ);
var store = trans.objectStore('msgs');
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound("");
var cursorRequest = store.openCursor(keyRange);
var res = new Array();
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false){
**res.sort(function(a,b){return Number(a.date) - Number(b.date);});**
//print res etc....
return;
}
res.push(result.value);
result.continue();
};

Javascript | Objects, Arrays and functions

may be you can help me. How can I create global object and function that return object values by id?
Example:
var chat = {
data : {
friends: {}
}
}
....
/*
JSON DATA RETURNED:
{"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
*/
onSuccess: function(f){
chat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends.push(f.users[i])
}
}
How can I create a new function (It will return values by friend_id)?
get_data_by_id: function (what, friend_id) {
/*obj.what = getfrom_globalobject(chat.data.friends???)*/
}
Example of use:
var friend_name = get_data_by_id(name, 62);
var friend_username = get_data_by_id(username, 62);
var friend_avatar = get_data_by_id(thumb, 62);
Try:
get_data_by_id: function (what, friend_id) {
return chat.data.friends[friend_id][what];
}
... but use it like:
var friend_name = get_data_by_id('name', 62);
...and set up the mapping with:
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i];
}
You cannot .push() to an object. Objects are key => value mappings, so you need to use char.data.friends[somekey] = f.users[i];
If you really just want a list with numeric keys, make x5fastchat.data.friends an array: x5fastchat.data.friends = [];
However, since you want to be able to access the elements by friend_id, do the following:
onSuccess: function(f){
x5fastchat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i]
}
}
get_data_by_id: function (what, friend_id) {
obj[what] = chat.data.friends[friend_id][what];
}
Note the obj[what] instead of your original obj.what: When writing obj.what, what is handled like a string, so it's equal to obj['what'] - but since it's a function argument you want obj[what].
Take a look at the following code. You can simply copy paste it into an HTML file and open it. click "go" and you should see the result. let me know if I did not understand you correctly. :
<script>
myObj = { "field1" : { "key1a" : "value1a" }, "field2" : "value2" }
function go()
{
findField(myObj, ["field2"])
findField(myObj, ["field1","key1a"])
}
function findField( obj, fields)
{
var myVal = obj;
for ( var i in fields )
{
myVal = myVal[fields[i]]
}
alert("your value is [" + myVal + "]");
}
</script>
<button onclick="go()">Go</button>
I would recommend using the friend objects rather than getting them by id and name.
DATA = {"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
// simple data store definition
Store = {items:{}};
NewStore = function(items){
var store = Object.create(Store);
store.items = items || {};
return store
};
Store.put = function(id, item){this.items[id] = item;};
Store.get = function(id){ return this.items[id]; };
Store.remove = function(id){ delete this.items[id]; };
Store.clear = function(){ this.items = {}; };
// example
var chat = {
data : {
friends : NewStore()
}
}
// after data loaded
chat.data.friends.clear();
for( var i = 0; i < DATA.users.length; i += 1 ){
var user = DATA.users[i];
chat.data.friends.put( user.friend_id, user );
}
getFriend = function(id){ return chat.data.friends.get( id ); }
var friend = getFriend(66);
console.log(friend.name);
console.log(friend.username);
console.log(friend.thumb);

Categories