How to use rootScope in angularjs - javascript

I have a data in my commonservice and I want to use the data in my template and I will assign a rootscope and use it but it isn't working right now and I am not sure what's wrong can anyone please suggest help.
My js:
function addGoogleAddress(id, data, scope) {
var places = new google.maps.places.Autocomplete(document.getElementById(id));
google.maps.event.addListener(places, 'place_changed', function () {
var place = places.getPlace();
if (place && place.address_components) {
for (var i = 0; i < (place.address_components.length); i++) {
if (place.address_components[i].types[0] === 'locality') {
data.city.key = '1001';
data.city.name = place.address_components[i].long_name.toString();
} else if (place.address_components[i].types[0] === 'administrative_area_level_1') {
data.state.key = '1001';
data.state.name = place.address_components[i].long_name.toString();
} else if (place.address_components[i].types[0] === 'country') {
data.country.key = '1001';
data.country.name = place.address_components[i].long_name.toString();
}
}
}
});
$timeout(function () {
$('#' + id).removeAttr('placeholder');
}, 500);
$rootScope.data = data;
}
My controller:
console.log($rootScope.data)
Here i am getting undefined.

You can not broadcast data directly, you need to broadcast event and pass parameter like follows,
Note: I am assuming here you have injected dependency
$rootScope.$broadcast('eventName',data);
Then in controller like follows -
$scope.$on('eventName',function(event,data){
console.log('data---',data);
})

app.controller('ctrl1',['$scope','$rootScope',function($scope,$rootScope) {
$scope.xyz = $rootScope.xyz;
//console.log($scope.xyz); hey
}]);
app.run(function($rootScope){
$rootScope.xyz ="hey";
})

Related

What is the best way to define a constant in an Angular controller?

I currently put my constants on the $scope. I don't feel like this is the best way to do it as anyone can access the scope with their JS console.
What is the best method to define constants in Angular?
var app = angular.module('app', []);
app.controller('calculatorController', function($scope) {
$scope.values = [];
$scope.CONSTANTS = {
ERROR_MESSAGES: {
NOT_INTEGER: "One of the values input was not a number!"
}
};
$scope.add = function () {
var calculatedValue = 0;
for (var i = 0; i <= $scope.values; i++) {
if (typeof $scope.values[i] === 'string' || $scope.values[i] instanceof String) {
alert($scope.CONSTANTS.ERROR_MESSAGES.NOT_INTEGER);
}
calculatedValue += $scope.values[i];
}
return calculatedValue;
}
});
Just make it a variable within the controller callback (or a const if using TypeScript or ES2015+ JavaScript):
var app = angular.module('app', []);
app.controller('calculatorController', function($scope) {
var ERROR_MESSAGES = {
NOT_INTEGER: "One of the values input was not a number!"
};
$scope.values = [];
$scope.add = function () {
var calculatedValue = 0;
for (var i = 0; i <= $scope.values; i++) {
if (typeof $scope.values[i] === 'string' || $scope.values[i] instanceof String) {
alert(ERROR_MESSAGES.NOT_INTEGER);
}
calculatedValue += $scope.values[i];
}
return calculatedValue;
}
});
(Though that particular kind of constant should probably be loaded from somewhere...)
If you want all the constants at one place, another way is to declare constants as below .
var app = angular.module('app', []);
angular.module('AppName').constant('versionConstant', {
"versionNum":"1.22"
});
// And inject them in your controller
angular.module(AppName).controller(ControllerName, ['$scope','versionConstant',
function ($scope, versionConstant) {
var version=versionConstant.versionNum;
});

Config is undefined for $scope.model property

I am implementing a controller for a content picker in Umbraco 7, where I need to change the start node to match a specific content node. However wen I load up the page with the content picker I receive an error saying:
"Cannot read property 'config' of undefined"
In relation to this piece of code:
$scope.model.config.StartNodeId = 1083;
if ($scope.model.config.StartNodeId) {
options.startNodeId = $scope.model.config.StartNodeId;
}
My entire controller:
angular.module("umbraco").controller("UIOMatic.FieldEditors.Pickers.ContentController",
function ($scope, $routeParams, $http, dialogService, entityResource, iconHelper) {
function init() {
if (!$scope.setting) {
$scope.setting = {};
}
var val = parseInt($scope.property.value);
if (!isNaN(val) && angular.isNumber(val) && val > 0) {
$scope.showQuery = false;
entityResource.getById(val, "Document").then(function (item) {
item.icon = iconHelper.convertFromLegacyIcon(item.icon);
$scope.node = item;
});
}
$scope.openContentPicker = function () {
var d = dialogService.treePicker({
section: "content",
treeAlias: "content",
multiPicker: false,
callback: populate
});
};
$scope.model.config.StartNodeId = 1083;
if ($scope.model.config.StartNodeId) {
options.startNodeId = $scope.model.config.StartNodeId;
}
$scope.clear = function () {
$scope.id = undefined;
$scope.node = undefined;
$scope.property.value = undefined;
};
function populate(item) {
$scope.clear();
item.icon = iconHelper.convertFromLegacyIcon(item.icon);
$scope.node = item;
$scope.id = item.id;
$scope.property.value = item.id;
}
};
if ($scope.valuesLoaded) {
init();
} else {
var unsubscribe = $scope.$on('valuesLoaded', function () {
init();
unsubscribe();
});
}
});
I tried changing the start node ID to 1083, which is what I want, and I can open the content picker just fine, but it won't allow me to save my changes. It also allows for multi-picking, which I have set to false in my config object.
This is the documentation of the content picker from the author:
http://uiomatic.readthedocs.io/en/stable/02.DefaultEditorViews/#content-picker
I think You should initialize $scope.model before assigning value to its object.
use
$scope.model = {}

Ionic application error: array.push() is not a function

I created an application where I have controller and factory. I have an array inside of the factory where I want to push id of the element to this array. However, when I am trying to push element to array I got an error that
"favorites.push is not a function"
Below you can find my controller and factory. Thank you for reading:
Factory:
.factory('favoriteFactory',['$resource', 'baseURL','$localStorage', function ($resource, baseURL, $localStorage) {
var favFac = {};
var favorites = $localStorage.get('favorites', []);
favFac.addFavorites = function (index) {
for(var i=0; i<favorites.length; i++){
if(favorites[i].id == index)
return
}
favorites.push({id: index});
$localStorage.storeObject('favorites',favorites)
}
favFac.deleteFromFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index) {
favorites.splice(i, 1);
}
}
$localStorage.storeObject('favorites', favorites)
};
favFac.getFavorites = function () {
return $localStorage.getObject('favorites',[]);
};
return favFac
}])
Controller:
.controller('MenuController', ['$scope', 'menuFactory', 'favoriteFactory','baseURL', '$ionicListDelegate', 'dishes', '$localStorage',
function($scope, menuFactory,favoriteFactory, baseURL, $ionicListDelegate, dishes, $localStorage) {
$scope.baseURL = baseURL;
$scope.tab = 1;
$scope.filtText = '';
$scope.showDetails = false;
$scope.showMenu = true;
$scope.message = "Loading ...";
$scope.addFavorite = function (index) {
console.log("index:" +index);
favoriteFactory.addFavorites(index);
$ionicListDelegate.closeOptionButtons();
};
$scope.dishes = dishes;
$scope.select = function(setTab) {
$scope.tab = setTab;
if (setTab === 2) {
$scope.filtText = "appetizer";
}
else if (setTab === 3) {
$scope.filtText = "mains";
}
else if (setTab === 4) {
$scope.filtText = "dessert";
}
else {
$scope.filtText = "";
}
};
$scope.isSelected = function (checkTab) {
return ($scope.tab === checkTab);
};
$scope.toggleDetails = function() {
$scope.showDetails = !$scope.showDetails;
};
}])
I assume you are using ngStorage. The get method does not have a second parameter. Therefore, your attempt at returning a default value of [](empty array) is simply returning undefined and then you are attempting to push to undefined and not to an array.
The source code for ngStorage shows no second parameter for get:
https://github.com/gsklee/ngStorage/blob/master/ngStorage.js
So this line:
var favorites = $localStorage.get('favorites', []);
Should be this:
var favorites = $localStorage.get('favorites') || [];

Moving code into a factory in an Angular app

I am trying to clean up a controller that has too many lines of code in it. In the controller below where you find a function called getProductDetails, I would like to move the filter to a factory or a service, but I am not sure how to do it.
'use strict';
(function () {
var userQuoteBuild = angular.module('priceApp');
userQuoteBuild.controller('quoteBuilderController', function ($scope, $http) {
// loads of controller logic here...
$scope.getProductDetails = function (item) {
$scope.listOfProductVariants = item.default_variant_attributes;
// TODO: put this in its own factory?
$scope.selectedProductAttributes = $scope.listOfAttributes.filter(function (item) {
var validated = false, i, length = $scope.listOfProductVariants.length;
for (i = 0; i < length; i++) {
if (item.name === $scope.listOfProductVariants[i]){
validated = true;
}
}
return validated;
});
};
});
(function () {
'use strict';
angular
.module('priceApp')
.factory('filterService', filterService);
function filterService() {
var service = {
getValidated: getValidated
}
return service;
function getValidated(list, variants) {
return list.filter(function (item) {
var validated = false, i, length = variants.length;
for (i = 0; i < length; i++) {
if (item.name === variants[i]) {
validated = true;
}
}
return validated;
});
}
}
})();
Simply inject this filterService to your controller and then use it as in example here:
$scope.selectedProductAttributes = filterService
.getValidated($scope.listOfAttributes,
$scope.listOfProductVariants)
I followed John Papa's AngularJS Style Guide. Make sure to choose a better name than filterService. : )
Check this:
userQuoteBuild.factory('myService', function() {
var service = {
getProductDetails: function(item) {
// your logic
return value;
}
}
return service;
});

How to scale controllers with angular

I have some angular app, that is really easy. I've put everything into one controller, but i want to split it into multiple controllers so every controller should do action that belongs to it, not have a lot of different function of different meaning in one controller.
Here is a code:
var videoApp = angular.module('videoApp', ['videoAppFilters', 'ui.unique', 'angularUtils.directives.dirPagination']);
videoApp.controller('VideoListCtrl', function ($scope, $http, $filter) {
$scope.getFilteredResults = function (category, data, callback) {
callback = callback ||$filter('articleFilter');
$scope.videos = callback(category, data);
return $scope.videos;
};
$scope.setPageSize = function (pageSize) {
$scope.pageSize = pageSize;
return $scope.pageSize;
};
$scope.addFavorite = function (data, key) {
localStorage.setItem(key, data);
$scope.getFilteredResults(data, $scope.allData);
return alert(key + " "+ data + " was added to your favorite list.");
};
$scope.addSelectedClass = function (event) {
if($(event.target).hasClass("selected") == true)
{
$(event.target).removeClass("selected");
} else {
$(".selected").removeClass("selected");
$(event.target).addClass("selected");
}
};
$scope.formatDate = function (dateString) {
var date = new Date(parseInt(dateString));
return date.toDateString();
};
$scope.cacheLoad = function (url, allowCache) {
if(allowCache == false || localStorage.getItem(url) && (parseInt(localStorage.getItem(url + 'time')) + 20000) < (new Date().getTime()) || (!localStorage.getItem(url) )) {
$http.get(url).success(function (data) {
$scope.allData = data;
$scope.videos = data;
if(localStorage.getItem('category')) {
$scope.videos = $scope.getFilteredResults(localStorage.getItem('category'), $scope.allData);
} else {
$scope.videos = data;
}
$scope.categories = $filter('categoryFilter')(data);
if(allowCache == true && parseInt(localStorage.getItem(url + 'time')) + 20000 < (new Date().getTime() )) {
localStorage.setItem(url, JSON.stringify(data));
localStorage.setItem(url + 'time', new Date().getTime());
}
});
} else {
$scope.allData = JSON.parse(localStorage.getItem(url));
$scope.videos = JSON.parse(localStorage.getItem(url));
$scope.categories = $filter('categoryFilter')(JSON.parse(localStorage.getItem(url)));
}
};
$scope.pageSize = 12;
$scope.cacheLoad('http://academy.tutoky.com/api/json.php', true);
});
So, how to split this into multiple controllers and how to pass data between them?
You could split things out into Services, for example the following item could be a service in your code, that you then dependency inject into your controller:
Your Cache logic, This is normally something you would want to reuse so it makes sense to be a service.
You might also want to make the following item a filter or directive:
$scope.formatDate - Rather than calling this function everytime you want to format a date, it would be much easier in your html to call {{ date | formatDate }} or <div formatDate>{{ date }}</div>
You could probably strip out the pageSize too but it depends how granular you want to go.

Categories