Using $scope in Angular - angularjs

I have a simple problem that I can't seem to figure out. I am new to angular.js and am trying ui.router. My web application is a table that displays JSON data.
The columns are all of the keys in a single JSON object, and the rows are the values for each respective key. I would like to do something like the following:
go to www.xyz.com/keyname,
and see all of the values for keyname.
However, I got stuck in trying to get the keys.
The keys are defined in a controller which is passed the data via a factory. I was then thinking I would do something like this:
var app = angular.module('SortingTables', ['ui.bootstrap', 'ui.router']);
app.factory('dataTable', function () {
return tastyJSONData;
});
app.controller('Ctrl', ['$scope', 'dataTable', function ($scope, dataTable) {
$scope.dataTable = dataTable;
$scope.columns = the keys in dataTable;
}]);
app.config(['$stateProvider', '$urlRouterProvider',function ($stateProvider,$urlRouterProvider) {
// pseudocode
for every column in $scope.columns in Ctrl
$stateProvider.state(column)...
}]);
However, I can't access the scope within the controller which contains the data. Am I missing something?
The config runs before the factory, so how can I access the data made by the factory in my config?

I believe it is best practice to keep all logic within the controller. Maybe go for something along the lines of:
app.controller('Ctrl', ['$scope', '$stateProvider', 'dataTable', function ($scope, $stateProvider, dataTable) {
$scope.dataTable = dataTable;
$scope.columns = the keys in dataTable;
// pseudocode
for every column in $scope.columns
$stateProvider.state(column)...
}]);
And then just leave your config for routing purposes
app.config(['$urlRouterProvider',function ($urlRouterProvider) {
//routing
}]);
Hard to say for sure without complete code. Hope this helps!

I think defining explicit states is making things harder than is required.
Try something like this:
.state('keys', {
url: '/',
resolve: {
keys: ['$http', function($http {
return $http.get('/api/keys');
}]
},
controller: function($scope, keys) {
$scope.allKeys = keys;
}
})
.state('keys.detail', {
url: '/:keyname',
controller: function($scope, $stateParams) {
$scope.keyname = $stateParams.keyname;
}
})
and in your view for 'keys' state something like:
<li ng-repeat="keyname in allKeys">
<a ui-sref="keys.detail({keyname: keyname})">{{ keyname }}</a>
</li>

Related

Angularjs JSON content inside ng-view

I am stuck in calling json text inside the ng-view. In normal HTML {{profile.experience}} this works perfect fine. fetching the data from json.
But since I have add the ng-view {{profile.experience}} is unable to fetch the data from json.
<div class="profile-snapshot">
<ul>
<li><span>Experience:</span><p> {{profile.experience}}</p></li>
<li><span>Education:</span><p> {{profile.education}}</p></li>
<li><span>Designation:</span><p>{{profile.designation}}</p></li>
<li><span>Age:</span><p>32</p></li>
<li><span>City:</span><p>Thane</p></li>
</ul>
</div>
This what my json look like
{
"experience": "Experience 8 Years asda s",
"education": "MBA, B.COM",
"designation": "UX Designer, Front End Developer"
}
this is what my angularjs code looks like
var accord = angular.module('accord', []);
var profileLoad = angular.module('profileLoad',[]);
var app2 = angular.module('main-app', ['accord','profileLoad','ngRoute']);
profileLoad.controller('profileCntrl', function($scope, $http){
'use strict';
$http.get('candidateProfile.json').success(function(data) {
$scope.profile = data;
});
});
app2.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'profile.html',
controller: 'StudentController'
})
.when('/viewStudents', {
templateUrl: 'profile-edit.html',
controller: 'StudentController'
})
.otherwise({
redirectTo: '/home'
});
});
can anyone please help me in fetching the json data inside ng-view?
Unless I'm missing something, I think
profileLoad.controller('profileCntrl', function($scope, $http){ ... }
should be
profileLoad.controller('StudentController', function($scope, $http){ ... }
You're retrieving the data in a controller that's not mapped to a template in $routeProvider.
Also, you should put your $http.get in a service and inject that service into your controller. Keep your concerns separated and your controllers lean.
Since I was already applying the controller. Only thing I needed to do is remove the controller: 'StudentController'.
That solved the problem for me.
I really appreciate the quick reply from the members here.
Cheers guys

Routing for multiple views in angular and mongodb

I am using Yeoman's angular-fullstack and am stuck on making multiple views based on Mongo's auto generated _id. The StoreCtlr, which populates all data to the pag,e works well, I am just having trouble passing in the parameter into the StoreShowCtrl
My controller is below:
storeControllers.controller('StoreShowCtrl', ['$scope', '$routeParams','$http',
function($scope, $routeParams, $http) {
$http.get('api/items'+$routeParams.items._id).success(function(detail) {
$scope.data = detail;
});
}
]);
I am routing with
.when('/product/:id', {
templateUrl: 'app/product/product.html',
controller: 'StoreShowCtrl'
});
Thank you for your help!
Use $routeParams.id instead $routeParams.items._id in controller, as you have mentioned id as param while defining state.
This will work.

How send send parameter for $routeProvider in angularJS

I want send parameter to templateUrl i want append some numbers after /folder/stockInventoryController.do?param=loadGroupStyles_Controller&fabId=(here I need to add)
myApp.config(function($routeProvider){
//setup Router for widgets page
$routeProvider
.when('/relatedStyle',{
controller:'groupStylesLoad',
templateUrl:'/folder/stockInventoryController.do?param=loadGroupStyles_Controller&fabId='+needParameterHere
})
});
templateUrl can be used as a function if you need to work some magic on the url. It accepts 1 parameter which takes in the current url.
Looking at your example, there aren't any parameters in /relatedStyle; but if there were you'd access and modify them like so:
.when('/relatedStyle/:arbitraryParam',{
controller:'groupStylesLoad',
templateUrl: function(url) {
var modifiedParam = url.arbitraryParam++;
return '/folder/stockInventoryController.do?param=loadGroupStyles_Controller&fabId=' + modifiedParam;
}
})
http://stackoverflow.com/questions/11534710/angularjs-how-to-use-routeparams-in-generating-the-templateurl
see above link ,it may be helpful for u
Here are two ways. One is routing
myApp.config(function($routeProvider){
//setup Router for widgets page
$routeProvider
.when('/relatedStyle/:fabid',{
controller:'groupStylesLoad',
templateUrl:'template/template.html'
})
});
myApp.controller("groupStylesLoad", ['$scope', '$routeParams',
function($scope, $routeParams)
{var fabId = $routeParams.fabid;}
]);
However, if you need to use the query sting.
myApp.controller("groupStylesLoad", ['$scope', '$location',
function($scope, $location)
{var fabId = $location.search().fabid;
// $location.search() returns object like {key1: value1, key2: value2, ...}
]);
https://docs.angularjs.org/guide/$location
Hope this helps.

how to execute the same init code on each controller instantiated by $routeProvider?

In my .config I have a router that instantiate a pair controller-router:
angular.module('reporting', ['ng', 'ngRoute', 'ngResource', 'reporting.directives', 'reporting.controllers', 'reporting.config', 'ngGrid', 'ui.bootstrap'])
.config(["$routeProvider", "$provide", function ($routeProvider, $provide) {
$routeProvider
.when('/dealersReq', {
templateUrl: 'reporting/partials/dealersReqs.html',
controller: 'DealersCtrl'
})
.when('/lmtReq', {
templateUrl: 'reporting/partials/lmt.html',
controller: 'lmtCtrl'
})
.when('/leadsCreated', {
templateUrl: 'reporting/partials/leadsCreated.html',
controller: 'LeadsCreatedCtrl'
})
...
but each controller share the same initialization code (think about it like a constructor) that sets in the rootScope some variable like a title and other useful information for some controllers outside the <view>:
.controller('DealersCtrl', ['$scope','$rootScope', 'CONFIG',
function($scope, $rootScope, CONFIG) {
//////////// duplicated code
var key = 'qtsldsCrtSncheQ';
$rootScope.openReport.key = key;
$rootScope.openReport.title = CONFIG.reports['' + key].title;
//////////// duplicated code
console.log('Initialized! Now I do what a controller should really do');
}]);
What I would like to do is finding a way to move that code - which is duplicated into every controller at the moment - into something smarter and neater. Soemthing that the route can call during the routing instanciation for example. Of course each controller should have a different key, but that one could be exactly the controller name actually. I really don't know how to improve this. Any suggestion?
Why don't create a method on the $rootScope which does that, and then call it from each controller, i.e.: $rootScope.init().
You could use a Service for shared code but you should avoid to use $rootScope
https://stackoverflow.com/a/16739309/3068081

Injection of angularFireCollection into angular.js config for usage in resolve

I've been experimenting a little with Angular.js lately. As part of this I created a very simple set of controllers with an ng-view and templates to trigger depending on the route requested. I'm using angularFireCollection just to grab an array from Firebase. This works fine in the thumbnailController which does not form part of the ng-view.
My problem is that in addition to the data flowing into the thumbnailController, I also need the two other controllers to be able to access the data. I initially simply set the data to either be part of $rootScope or to have the ng-view as a child of the div in which the thumbnailController is set.
However, the issue from that perspective is that each sub-controller presumably attempts to set the data in the template before it is actually available from Firebase.
The solution appears to be using resolve as per the answer to this question angularFire route resolution. However, using the below code (and also referencing angularFireCollection) I get an error message of angularFire being an unknown provider. My understanding is the code below should be sufficient, and I would also add that the usage of angularFireCollection in thumbnailController works fine as I say.
I also experimented with injecting angularFire/aFCollection directly into the controllers using .$inject however a similar issue arose in terms of it being considered an unknown provider.
If possible could someone advise on what the issue may be here?
var galleryModule = angular.module('galleryModule', ['firebase']);
galleryModule.config(['$routeProvider', 'angularFire', function($routeProvider, angularFire){
$routeProvider.
when('/', {
controller: initialController,
templateUrl: 'largeimagetemplate.html',
resolve: {images: angularFire('https://mbg.firebaseio.com/images')}
}).
when('/view/:id', {
controller: mainimageController,
templateUrl: 'largeimagetemplate.html',
resolve: {images: angularFire('https://mbg.firebaseio.com/images')}
}).
otherwise({
redirectTo: '/'
});
}]);
galleryModule.controller('thumbnailController', ['$scope', 'angularFireCollection', function($scope, angularFireCollection){
var url = 'https://mbg.firebaseio.com/images';
$scope.images = angularFireCollection(url);
}]);
function initialController($scope,images){
$scope.largeurl = images[0].largeurl;
}
function mainimageController($scope, images, $routeParams){
$scope.largeurl = images[$routeParams.id].largeurl;
}
I got the chance to dig into this a little bit - it seems like regular services cannot be used in .config sections. I'd instantiate angularFire in the controller instead of using resolve, for example:
galleryModule
.value("url", "https://mbg.firebaseio.com/images")
.controller('thumbnailController', ['$scope', 'angularFireCollection', 'url',
function($scope, angularFireCollection, url) {
$scope.images = angularFireCollection(url);
}])
.controller('initialController', ['$scope', 'angularFire', 'url',
function($scope, angularFire, url) {
angularFire(url, $scope, 'images').then(function() {
$scope.largeurl = $scope.images[0].largeurl;
});
}])
.controller('mainimageController', ['$scope', 'angularFire', '$routeParams', 'url',
function($scope, angularFire, $routeParams, url){
angularFire(url, $scope, 'images').then(function() {
$scope.largeurl = $scope.images[$routeParams.id].largeurl;
});
}]);
This is not ineffecient, since the data is only loaded once from the URL by Firebase, and all subsequent promises will be resolved almost immediately with data already at hand.
I would like to see angularFire work with resolve in the $routeProvider, however. You can use this method as a workaround until we figure out a more elegant solution.

Resources