I use ngStorage (https://github.com/gsklee/ngStorage) for storing some data in the localStorage of the browser.
I have this markup
<ul class="cards">
<li ng-repeat="card in cards">
<card></card>
</li>
</ul>
With a "card" (as u can see) directive, that stores my template for each card.
In my Controller I have this method to push a card in the ng-repeat Array of cards:
angular.controller('CustomerController', function($scope, $localStorage, $sessionStorage) {
$scope.cards = [];
$scope.addCardRed = function() {
return $scope.cards.push(new Card("red"));
};
(...)
});
That works so far. But I can't accomplish to store the cards in my ul. I tried some variations of:
(...)
$scope.$storage = $localStorage;
$scope.cards = [];
$localStorage.cards = [];
$localStorage.cards = $scope.cards;
But either my cards won't displayed in the list anymore or the list won't be stored. What can I do to store my card elements in the list? What am I doing wrong?
I think, your Card is not a Simple JavaScript Object. therefore you may want to use something like this:
angular.module('storage',[]).factory('cardStorage',function(){
var key = 'cards';
var store = localStorage;
// Card has to be JSON serializable
function assign(value){store[key]=JSON.stringify(value)};
// return Card instances
function fetch(){return (JSON.parse(store[key])||[]).map(
function(card){return new Card(card);
})};
return {
bind:function(scope,attribute,defaults){
// read from storage - in case no data in scope
if(!(attribute in scope)){
scope[attribute]=fetch();
}
// observe changes in cars and persist them
scope.$watch(attribute,function(next,prev){
assign(next);
},true);
}
}
});
and in your Controller
function(scope,cardStorage){
cardStorage.bind('cards');
}
or you can use :
https://github.com/agrublev/angularLocalStorage
Related
when I am at the home page and click on the link in the navigation bar
<li class="nav-item" ng-show="currentUser">
<a class="nav-link" ng-show="currentUser"
ng-href="#/pictures"">Pictures</a>
</li>
It goes to the page, I can see the data is downloaded but it is not shown in the UI when update $scope.urlListUI.
urlListInRoomUnits=loadPicture(filePathInRoomUnitPicture);
$scope.urlListUI=urlListInRoomUnits;
$scope.$apply();
console.log('update ui: '+urlListInRoomUnits);
however, if I refresh the page, it will work.
the UI code
<div ng-repeat = "urlRecord in urlListUI">
<p>{{urlRecord[1]}}</p>
<img ngf-src="urlRecord[0]" class="img-thumbnail">
</div>
the function: loadPicture(filePathInRoomUnitPicture)
function loadPicture(pictureTypeFolder){
console.log('loadpicture is running, input parameter:'+pictureTypeFolder);
var urlList=[];
$scope.whereThePictureIs=pictureTypeFolder;
//list image from firebase storage
var storageRefDownloadByPictureType = storageRef.child('airconPicture').child(pictureTypeFolder);
storageRefDownloadByPictureType.listAll()
.then(function(result) {
console.dir(result);
result.items.forEach(function(imageRef) {
// And finally display them
imageRef.getDownloadURL()
.then(function(url){
// TODO: Display the image on the UI
urlList.push([url,imageRef.name]);
})
.catch(function(error) {
// Handle any errors
});
});// end of for each download
})// end of list all promise
.catch(function(error) {
// Handle any errors
});
return urlList;
};// end of load Pciture by type
thanks for helping or direct me to the right source.
So what I see, first, you try to resolve storageRefDownloadByPictureType.listAll()
After resolving (let's say 1 sec), you run in a loop on results and try to resolve a list of items:
result.items.forEach(function(imageRef) {
imageRef.getDownloadURL().then(function(url){
})
You resolve all at once, let's say, another 1 sec.
Your method does not return promise but empty urlList because you populate it in the next 2 seconds.
So instead urlListInRoomUnits=loadPicture(filePathInRoomUnitPicture);
It should be something like (you can write loadPicture in some service, lets say MyService):
MyService.loadPicture(filePathInRoomUnitPicture).then(function (urls) {
//here you get all your results
$scope.urlListUI = //...
});
and now loadPicture in MyService:
this.loadPicture = function(filePathInRoomUnitPicture){
//...
return storageRefDownloadByPictureType.listAll().then(function(result) {
// create list of promises:
var promises = [];
result.items.forEach(function(imageRef) {
promises.push(imageRef.getDownloadURL());
})
// chain promises
return $q.all(promises);
};
I am trying to display the items using ng-repeat and when the list is initailly loading , trying to call another service to get the details about the first item.
Here is my code:
<div ng-repeat="item in itemList">
<div ng-click="setCurrentItem(item,$index)" ng-init="initCurrentItem(item,$index)">
item.id
</div>
</div>
In controller:
function init(){
itemService.loadItem();
}
$scope.itemList = function(){
return itemService.getItemsList();
}
from this service I am getting the following data :
itemName:x001,
item.id:10
itemName:x002,
item.id:20,
itemName:x003,
item.id:30.
I am calling another service to get itemDetails.
$scope.currentItemDetails ={};
$scope.currentItemDetails.id ='';
$scope.initCurrentItem(item.index){
if(scope.currentItemDetails.id === ''){
$scope.setCurrentItem(item.index);
}
}
$scope.setCurrentItem = function(item,index){
item.index = index;
itemService.loadItemDetails(item.id).then(function(response){
if(angular.isDefined(response)){
$scope.currentItemDetails = response.data;
}
});
when the list loading initailly and calling initCurrentItem, the currentItemDetails holding last item (itemName:x003,id:30). ng-repeat is repeat the values without waiting response from the service. How do I wait in the loop until I get response from first item?
Just use the same logic in init method as you have in the other example - with .then( etc. And assign value to the repeating variable itemList. Then table HTML will be refreshed automagically when the data arrives and Promise will be resolved:
<div ng-repeat="item in itemList">
function init(){
itemService.loadItem().then(function(response){
if(angular.isDefined(response)){
$scope.itemList = response.data;
}
});
}
UPD
try calling initCurrentItem after the data is loaded
function init(){
itemService.loadItem().then(function(response){
if(angular.isDefined(response)){
$scope.itemList = response.data;
//here we iterate received array $scope.itemList and call initCurrentItem on each of them
$scope.itemList.forEach(function(item, i){
$scope.initCurrentItem(item, i);
});
}
});
}
I have an app where I need to store artists and their details in database.Now I want to retrieve all the artists and render some of their details in front end.How to do that.
Secondly, if I get the artist rating in some input field by using ng-model, then how to store that value in a particular artist to update details.
The database structure is:
{
"artists": {
"Atif":{
"name":"atif",
"rating":8
},
"Himesh":{
"name":"himesh",
"rating":5
}
}
}
and this is angular.js
(function()
{
var app = angular.module("myapp", ["firebase"]);
app.controller("maincontroller", function($scope, $firebaseObject,$firebaseArray)
{
var ref = new Firebase("https://gigstart.firebaseio.com/");
var artists=ref.child("artists");
// download the data into a local object
$scope.data = $firebaseObject(ref);
// putting a console.log here won't work, see below
ref.on("value", function(snapshot)
{
console.log(snapshot.val());
}, function (errorObject)
{
console.log("The read failed: " + errorObject.code);
});
var artistsRef=new Firebase("https://gigstart.firebaseio.com//artists");
}); //end of controller
Now I want to render the name and rating of each artist in front end.Can I do something like
<div ng-repeat="artist in artists">
{{artist.name}}
{{artist.rating}}
</div>
You have a list of artists, which you want to ng-repeat over in your Angular view. You can accomplish that by:
app.controller("maincontroller", function($scope, $firebaseArray)
{
var ref = new Firebase("https://gigstart.firebaseio.com/");
var artists = ref.child("artists");
$scope.artists = new $firebaseArray(artists);
}
Please take a moment to go through the AngularFire quickstart before starting on your own project. This is covered in step 5.
By clicking the link i change view, this re-instantiating my controller. This is why the activeMenu is empty. If icreate a service and store the currently active menu in there, it won't be empty.How can i create service to do that? This is my first time that i need to create service?This is my plnkr... http://plnkr.co/edit/gJko3umteXXEye7o9StR?p=preview
Problem is when user click on menu from layout then this re-instantiating my controller
Layout:
<li class="dropdown">
<ul class="submenu">
<li>#Translate("MY_ACCOUNT")</li>
<li ng-click="GetLoader();">#Translate("SETTINGS")</li>
<li ng-click="GetLoader();">#Translate("TICKET_HISTORY")</li>
<li ng-click="GetLoader();">#Translate("TRANSACTIONS")</li>
<li ng-click="GetLoader();">#Translate("BONUS_ACCOUNT")</li>
<li>#Translate("ODDS_REPRENSETATION")</li>
<li>#Translate("HELP")</li>
<li>#Translate("LOGOUT")</li>
</ul> </li>
You can do it like this:
app.service('navigation', function () {
this.activeLink = '';
});
app.controller('MainCtrl', function($scope, navigation) {
$scope.activeMenu = 'Home';
$scope.activeLink = navigation.activeLink;
$scope.changeActiveLink = function(link) {
$scope.activeLink = link;
this.activeLink = link;
}
});
The service is a singleton, it's intatiaded once per you application load, so it will keep the assigned value between diffent states of your app.
You can make it a bit smarter if you won't store a simple string value but an object - this way we'll be able to keep the reference to the service's value rather than the value itself and we won't need to set both $scope.activeLink = link; and this.activeLink = link; explicitly:
app.service('navigation', function () {
this.active = {
link: '',
menu: 'Home'
};
});
app.controller('MainCtrl', function($scope, navigation) {
$scope.activenav = navigation.active;
$scope.changeActiveLink = function(link) {
navigation.active.link = link;
}
});
(just remember to make necessary changes in your html code in that second case)
I just give a try to AngularJS. I try to do something quite simple but I'd like to do it the good way.
I got a list of items in a table which displays name and quantity for each item.
I have a form under the table.
When I click on an item name from the table I'd like the given item to be updatable through the form.
I achieve to do thing with scope inheritance as in fiddle http://jsfiddle.net/5cRte/1/
View :
<tr ng-repeat="item in items">
<td>{{item.name}}</td>
<td>{{item.quantity}}</td>
</tr>
Controllers :
function ItemListController($scope){
$scope.items = [{name:'item1', quantity:10}, {name:'item2', quantity:5}];
$scope.selectCurrentItem = function(currentItem) {
$scope.currentItem = currentItem;
}
}
function ItemFormController($scope){
$scope.$watch('currentItem', function() {
$scope.item = $scope.currentItem;
});
}
But has I read in some topics, it is not a good practice to couple controllers scopes this way, and preferably I'll wan't to use a service to store variables shared between controllers.
I was able to put a static variable in a service and retrieve it in another controller, but I can't make it updated when clicking on the item from the table, as watch not working on services variable. Have you an hint, for this ?
Thanks in advance
I don't know whether this is optimal but this what I could come up with
angular.module('myApp', []);
angular.module('myApp').factory('myService', function(){
var items = [{name:'item1', quantity:10}, {name:'item2', quantity:5}, {name:'item3', quantity:50}];
var current = {};
return {
getItems: function(){
return items;
},
setCurrentItem: function(item){
current.item = item;
},
removeCurrentItem: function(){
delete current.item;
},
getCurrent: function(){
return current;
}
}
});
function ItemListController($scope, myService){
$scope.items = myService.getItems();
$scope.selectCurrentItem = function(currentItem) {
myService.setCurrentItem(currentItem);
}
}
function ItemFormController($scope, myService){
$scope.current = myService.getCurrent();
}
Demo: Fiddle