AngularJS storing array of objects in a cookie - angularjs

I have an array of objects stored in the scope variable. The issue with that is when the user refreshes the page, it does not persist that data, so I am considering using cookies.
The variable $scope.Users stores an array of user objects and I am using the following code to get that data into a cookie:
if ($cookies.getObject('user_data') === '' || $cookies.getObject('user_data') === undefined)
$cookies.putObject('user_data',$scope.Users);
Which does not display any data is I use
console.log($cookies.getObject('user_data'))
and I am not getting anything back, so it seems that putObject does not save the data. What could be wrong here? Could the size of the cookie exceed the limit?
Previously I used the following to retrieve that data from my html page:
<tr ng-repeat="User in Users">
<td>{{User.Name}}</td>
<td>{{User.ID}}</td>
<td>{{User.DOB}}</td>
<td>{{User.Status}}</td>
</tr>
My question is how to I retrieve the array from cookies and display its contents? Also is there a better way to persist an array of objects through refresh? Would service work better?

you can try this code.
var obj = {"Name": name, "ID": id, "DOB": dob, "Status": status};
$scope.Users.push(obj);
$cookies.put('user_data', JSON.stringify($scope.Users));
var s = $cookies.get('user_data');
$scope.Users= JSON.parse(s);

Make sure you inject ngCookies as a dependency to the module,
angular.module('cookiesExample', ['ngCookies'])
You can do this in controller,
To set data
$cookies.user_data = $scope.users;
To retrieve data
$scope.Users= $cookies.user_data;
HTML
<tr ng-repeat="User in Users">
<td>{{User.Name}}</td>
<td>{{User.ID}}</td>
<td>{{User.DOB}}</td>
<td>{{User.Status}}</td>
</tr>
DEMO

I recreated your scenario without issues. What version of $cookies are you using? It should match your angular version.
As for persisting data, the only other option I can think of would be to save it to a server. A service wouldn't work as the refresh would clear it out too.

Related

How to make a table sort-able while the whole components is passed as string via ng-bind-html in AngluarJS

Hi I have a situation in AngluarJS that the HTML is generated by back-end and the only thing that front-end should do is to put the HTML which is mostly table tags into the ng-bind-html and show it to the user. But now these tables should be sort-able too. How can I do it?
The thing that I've already done is to create my own directive using this so make the static string HTML take some actions too. But having them sorted is something else. In other word I want to make my fully generated table with all <tr> and <td> to get sorted by my actions.
Here is my simplified code (compile is my directive):
JS:
// The string is fully generated by back-end
$scope.data.html =
'<table> <tr> <th ng-click="sortByHeader($event)"> Name </th>
<th ng-click="sortByHeader($event)"> Age </th> </tr>
<tr> <td> Sara </td> <td> 15 </td> </tr>
<tr> <td> David </td> <td> 20 </td> </tr>'
HTML:
<div compile="data.html"></div>
The ng-click="sortByHeader($event) is something that back-end can prepare for me so I can use it thanks to the compile I wrote that let me find out which header has been clicked. Other than that there is nothing I can do. Unless you can help me :D
Thanks in advance, I hope my question was clear.
Since you tagged your question with sorttable.js I'm going to assume that you are using that script to sort your tables.
Now, if I understand it correctly, sorttable.js parses your HTML for any tables with the class sortable. Your table is apparently loaded dynamically, therefore sorttable.js does not know about it when it parses the HTML.
But you can tell it to make a dynamically added table sortable, too.
Relevant part taken from the following page:
https://kryogenix.org/code/browser/sorttable/#ajaxtables
Sorting a table added after page load
Once you've added a new table to the page at runtime (for example, by
doing an Ajax request to get the content, or by dynamically creating
it with JavaScript), get a reference to it (possibly with var
newTableObject = document.getElementById(idOfTheTableIJustAdded) or
similar), then do this:
sorttable.makeSortable(newTableObject);
You should be able to do that with angular. If not, I can try to put something together later.
Is the answer to the question "Does the rendered table have to exactly match the HTML retrieved by the backend?" a kind of "No"?
If that's the case, then here's a hacky way of gaining control of the table contents by parsing and capturing stuff from the backend HTML string using regular expressions.
For example: grab all row data and apply sorting client side
// Variables to be set by your sortByHeader functions in order to do client-side sorting
$scope.expression = null;
$scope.direction = null;
var regexToGetTableHead = /<table>\s*(.*<\/th>\s*<\/tr>)/g;
$scope.tableHead = regexToGetTableHead.exec($scope.data.html);
$scope.tableRows = [];
var regexToGetRowContents = /<tr>\s*<td>\s*(\w*)\s*<\/td>\s*<td>\s*(\w*)\s*<\/td>\s*<\/tr>/g;
var match;
while ((match = regexToGetRowContents.exec($scope.data.html)) != null) {
$scope.tableRows.push({
"name": match[1],
"age": match[2]
});
}
And HTML
<table>
<thead compile="tableHead"></thead>
<tbody>
<tr ng-repeat="row in tableRows | orderBy: expression : direction">
<td>{{row.name}}</td>
<td>{{row.age}}</td>
</tr>
</tbody>
</table>

Is the AngularJS smart-table documentation/demo buggy?

I just don't understand this. On the smart-table web page, where it discusses the stSafeSrc
attriubute, I don’t see where $scope. displayedCollection gets declared.
The text says smart-table first creates a safe copy of your displayed collection, and I
I had assumed that a smart-table directive was declaring it, but the sample code won’t work for me – the table rows are empty - and that’s what looks to me to be the problem.
If we look, for instance, at the accepted answer to this question, we see the user declaring $scope.displayedCollection as an empty array and assigning it a value when the AJAX response is received. BUT, the documentation doesn't mention that.
<table st-table="displayedCollection" st-safe-src="rowCollection">
<thead>
<tr>
<th st-sort="firstName">First Name</th>
<th st-sort="lastName">Last Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayedCollection">
<td>{{row.firstName}}</td>
<td>{{row.lastName}}</td>
</tr>
</tbody>
</table
app.controller('Ctrl', function($scope, service) {
$scope.displayedCollection = [];
service.all.then(function(list) {
$scope.rowCollection = list;
$scope.displayedCollection = list;
});
});
So, do I need to care for the copy myself? And does the documentaion need to be updated? And how does the demo work?
[Update] I find this on the github issues, by #tufan-yoc
you have to copy the data array to an other variable in the scope:
st-table="displayedCollection" st-safe-src="rowCollection"
and
//copy the references (you could clone ie angular.copy
// but then have to go through a dirty checking for the matches)
$scope.displayedCollection = [].concat($scope.rowCollection);
If this truly is a requirement, why is it not explictly documented?
And why does the example on the smart-table website work without it?
You don't need to copy anything. what you set with the attribute st-table is simply a placeholder for your templates (ie a variable in the scope) which you will likely use in the row repeater, it does not have to be declared anywhere, smart-table will assign the items to be displayed to this variable so your templates can be updated.
your source of truth (ie your data) should be the collection you bind to st-safe-src attribute. Whenever the bound collection changes, smart table will update a local copy so it can perform the filter/sort/slice operations based on the latest and actual data.
However for convenience (and performance), if you don't intend to modify your data (or its arrival is not delayed like with ajax fetch) the internal copy is firstly based on any collection bound to the variable in the scope designed by the st-table attribute.
Note in this case, the value will be erased and replaced by the displayed collection so the template is updated. Fortunately the initial copy will persist as private variable of smart-table.
If you encounter a problem it likely comes from somewhere else. If so please provide a running example (with angular version and smart table version)
No, it's not buggy. SmartTables will create an $scope.displayedCollection object or whatever name you use for the array that will hold a copy of the original data if you use the stSafeSrc attribute. If it doesn't show you any data check your rowCollection object, it should contain the original array. If you are working in Chrome try the ng-inspector for AngularJS so you can see the scope of your app. Also if you could post a plunker of your code it will be better.
We can show that the user must take action to make acopy and keep it in synch with AJAX data, by looking at this Plunk (which is not mine).
If we comment out line 18:
$scope.displayedCollection = [].concat($scope.rowCollection);
as per the online example, the table becomes empty.
Conclusion: the website documentation is wrong to say
smart-table first creates a safe copy of your displayed collection
And, bizarrely, the (working) example on the website ... should not work (?)

how to call a value from array in AngularJS controller?

I have an array like this:
$scope.persons = [{name:'Joey', age:'27'}]
I can call the value in HTML in this way
{{person.name}}
But when I try something like this, it fails
$scope.name = $routeParams.person.name
I could read the person only (without .name), it will be displayed as an array.But I want to access to the name key. Thx in advance.
I pass the person to JS in this way (route)
<tr data-ng-repeat="person in persons">
<td headers="more">
Show Details
</td>
</tr>
Try below code, as you are accessing value from array, whenever you access value from array need to mention index.
$scope.name = $routeParams.persons[0].name
Try This
Show Details

How to display db result array in Twig using Angular.js in Symfony 2.3?

I am trying to include angular.js in my project which is created using Symfony 2.3.
I converted the result array to json using json_encode function in controller
function displayAction(){
$user= $this->getDoctrine()->getRepository('DemoBundle:Users');
$result = $user->findAll();
$res= json_encode($result);
$res->header->set('Content-Type', 'application/json');
return $this->render('DemoBundle:Demo:demoView.html.twig',array('results'=>$res));
}
to initialise it in ng-init,
<div ng-init= "result= {{results}}"></div>
<table>
<tr ng-repeat="res in result">
<td>[[res.id]]</td>
<td>[[res.username]]</td>
<td>[[res.password]]</td>
</tr>
</table>
but it gives me an empty array of json.
I guess it has no sense return a json to process it in the Twig template. Maybe you need to ask for the json resource on angularjs controller (with $http or via $resource) and get the data from the model (no ng-init).
If you still want to do it, maybe you get some help from here: Decoding JSON in Twig

Unable to add more than one model to my collection

I am new to Backbone, and trying to make a table data using backbone, it has add, edit, delete (CRUD).
In this process I've done the add part, all works fine. But I'm unable to add more than one person using create new list button. Any one assist me to figure out the issue and how to fix this?
Here is the excerpt:
template:
<tbody>
<% _.each(users, function(user){ %>
<tr>
<td><%= user.get("firstName") %></td>
<td><%= user.get("lastName")%></td>
<td><%= user.get("age") %></td>
<td>Edit</td>
</tr>
<%})%>
</tbody>
// function
render:function(){
var template = _.template($("#listTempalate").html(), {users:this.collection.models});
this.$el.html(template)
},
Here is the jsfiddle
Thanks in advance.
When you push the data to your array, you're not adding an id property.
The "created" data are all sharing the same (non-existant) id, and a backbone collection only allows a single instance of the same model (based on the id). So, only the first of the created models is being added to the collection.
What you would do in a real Backbone app is either create a new userModel with the entered data and .add() that to the collection, or just call .add() on the collection with the raw data.
For your demo, you could just generate an id property before you push the data to the array.

Resources