How to move an object to the top of an array with AngularFire? - javascript

I am trying to move an object to the top of an array with AngularFire.
My array in Firebase is simmilar to this:
$scope.todos = [
{title:"Work out", timetag:"new Date()", done: false },
{title:"Home work", timetag:"new Date()", done: false }
];
I created a function that uses vanilla javascript that stores the object to a variable. The function deletes the object from the array that you want to move up to the beginning of the array. The function then replaces the object you stored to a variable to the beginning of the array.
Here is the code I have:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index];
delete $scope.todos[$index];
$scope.todos.splice(0,0, toMove);
$scope.todos.$save();
};
This code snippet is almost completely working the way I want. When I run this on my todo list, It moves the todo task up the array. However when I refresh the page, it doesn't stick.
What are the appropriate AngularFire Methods to completely save or set this type of javascript code to my Firebase Backend?

To preserve the order of the TODOs you could add a property named for example priority.
When a TODO is dragged/moved up the priority list you should then re-set the priority values of the TODOs save them and order them by that property in your template.

Okay so array methods like splice(), push(), pop(), shift(), unshift(), and reverse() will cause the Firebase Array to break.
So my work around was to edit/change the array with standard Javascript Array methods.
Then I store a copy of the local(edited)state array to a variable.
Then I delete the Firebase array.
Then I pushed the keys of the local array to Firebase.
Here is the code below:
$scope.moveUpPriority = function($index){
var toMove = $scope.todos[$index]; //save copy of $index todo
$scope.todos.splice($index,1); //removes item at $index
$scope.todos.splice(0,0, toMove); //adds item toMove to the start of array
var backup = $scope.todos; //copy back up array
for(var b = 0; b<= $scope.todos.length; b++){
$scope.todos.$remove($scope.todos[b]); //remove items from array
}
for(var i = 0; i<= backup.length; i++){
$scope.todos.$add(backup[i]); // add items from back up array
}
};

Related

How to store <div> elements to localStorage?

I´m trying to set an array of items(divs) to Local Storage for when the page reloads these elements being shown in the Ui. The function checks if there is an array already stored with that name, and if so, the local storage must clean this item and then set the array updated whit these items that were added in another part of the code. But when I see what local storage is returning after I set this array I find an array with empty objects with the same length that would must have, and in this same function before I set the array is correct with all the items there.
What am I missing?
function setToLocalStorage(){
console.log(items); //the is array is there with all items
if(!!localStorage.getItem("items")){
localStorage.removeItem("items");
}
localStorage.setItem("items",JSON.stringify(items));
}
function getDataFromLocalStorage(){
let elements=JSON.parse(localStorage.getItem('items'));
console.log(elements); //I get an array with empty objects with the same length of the first
}
to set an array of items(divs) to Local Storage
The localStorage code is fine, the thing is that you cannot simply JSON-serialise a DOM element.
For example, this code:
let el = document.createElement('div');
el.textContent = "Test";
console.log('element:', el);
console.log('element to JSON:', JSON.stringify(el));
will output:
element: <div>​Test​</div>​
element to JSON: {}
So you will need to use JSON.stringify on the actual data that you used to create those DIVs.

Checking for existing array in array before pushing

I missing something when trying to push to an array while preventing duplicates.
I keep figuring out code that will push every occurence of an employee to the new employees array but I cannot figure out how to only push an unique list.
My final array is a 2d array so that can be setValues() back into a column in the Google sheet.
function queryEmployees(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lRow = sh.getLastRow();
var data = sh.getRange(1,1,lRow,2).getValues();
var employees = [];
for(i=0;i<data.length;i++){
if(data[i][0]==='Team member evaluated'){
if(employees.indexOf([data[i][1]])===-1){
employees.push([data[i][1]]);
}
}
}
Logger.log(employees);
Logger.log(employees.length);
SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]
.getRange(1,1,employees.length,1).setValues(employees);
}
IndexOf does not work with objects in arrays without your rewriting the function or writing your own. It works fine with strings, though. So a simple fix is to create a parallel array of strings, which allows us to keep your code almost intact. Thus, add,
var employeesIndex=[];
after your
var employees=[]
change the condition on your inner "if" clause to
(employeesIndex.indexOf(data[i][1])===-1)
and within that if block add a line to update the index
employeesIndex.push(data[i][1]);
That way the index tracks duplicates for you while your employees array contains arrays like you need.

Firebase - push an object in a nested list of objects

Firebase - push an object in a nested list of objects
Current attempt:
this.application.userUid = this.uid;
this.application.companyUid = job.uid;
this.application.jobName = job.name;
this.application.jobDescription = job.description;
this.application.jobId = job.id;
this.refApp.child(this.uid).child(job.id).push(this.application);
Currently the object is added but nested too low down. It needs to be like the second object in the list.
uid --> jobid -> then the object.
Here is my database:
Use .set(), instead of .push()
this.refApp.child(this.uid).child(job.id).set(this.application);
However, if you want to generate an id with .push() you can move back one level in the data structure:
this.refApp.child(this.uid).push(this.application);

Storing values in array and retrieving from array when checkbox is checked

I am storing some values in array like this.
var test = [];
I am pushing the values to this array as test.push(sample);
I have some logic for calculating this value
var sample= (a/b.length)*100;
When I click on a button, the above logic for calculating value of sample is done and once I got the value of sample I am pushing it to test[] array. Now I want to retrieve all the values from the test[] array whenever I check the checkbox. I am able to do all this but I am facing a problem here. only the last pushed value is saving. but I want to save all the values that are being pushed. can anyone please help me in solving this issue.
Quick response is needed and appreciated
Regards
Hema
You need to use 2 dimensional array for this.
Use
var test= new Array();
then assign value test['someKey']=sample;
or test.push(sample); . you can retrieve array value like alert(test[0]) or by iterating array with $.each(test,function(index,value){alert(value)});
What you want to do is create an Array which would function as a list of value sets.
You would then be able to push all the changes into an array, and put it in the list.
for instance:
var mainList = new Array();
var changeListA = new Array();
var changeListB = new Array();
// do some stuff on change list **a** .. push(something)
changeListA .push(something);
changeListA .push(something);
changeListA .push(something);
// do some stuff on change list **b** .. push(something)
changeListB .push(changeListB);
mainList.push(changeListA);
Your question is not perfectly clear to me, however I can at least provide a small jsFiddle that proves to you that (how) array.push works.
Other answers indicate that what you want is either a two dimensional array, or a "hashmap" or "associative array" where the array values are stored using a key name. The code here can be used in the fiddle to achieve either or...
http://jsfiddle.net/xN3uL/1/
// First if you need 2 dimensional arrays:
myArray.push( ["Orange", "Apple"] );
myArray.push( ["Mango", "Pineapple"] );
// Secondly, if you need hashmap or associative array:
var myObj = {};
myObj['key'] = 'value';
alert(myObject.key);

How Do I Make an Array of Objects a Reactive Data Source?

I have an array of objects. Say
var
sidelist = [
{
name:"asdf",
id:1234,
types:[...]
}
];
Every object is turned into a box on the page using this construct
Template.global.side = function(){
var obj = [], m;
m = 1;
for (var i in sides){
obj.push({
index : m,
object : sides[i]
});
}
return obj;
}
The HTML:
{{#each side}}
<div class="span{{this.index}}" id={{this.object.id}}>
<div class="side-head">{{this.object.name}}</div>
</template>
There is a function that creates and pushes a new object into the array. How do I make the row of boxes reactively update on the page when the array they depend on changes?
So when I add a new object a new box should appear.
If you want to use Dependencies, it can look like this:
var sidelist = ...;
var sidelist_dep = new Deps.Dependency;
Template.global.side = function(){
sidelist_dep.depend();
// Do your stuff here;
return ...;
};
// Important: call this every time you change sidelist,
// AFTER the change is made.
sidelist_dep.changed();
See: http://docs.meteor.com/#deps
In almost all cases, you should put the objects in a Meteor Collection instead of an array that is part of a reactive object. There are many reasons for this, including the following
Adding, removing, searching, and updating will all be faster
The reactivity will be on the element level instead of the array
Meteor won't re-render the whole set of objects when something is added or deleted - just the change
You can define a sort order on the collection, making it much more flexible than a fixed sequence
Take a look at Andrew Wilcox's isolate-value smart package:
https://atmosphere.meteor.com/package/isolate-value
The README contains the exact example of selectively rerendering relevant templates when values are added/removed from an array stored in a Session varaible.

Categories