Run function of one angular controller in another controller - javascript

I have page with 2 lists: categories and products for that category. Module code:
var shop = angular.module('shop', []);
shop.controller('Products', ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
$scope.products = [];
$scope.update = function () {
$http.post('/shop/products', {
category_id: $rootScope.category_id
})
.success(function(response, status){
$scope.products = response.data;
})
.error(function(data, status){ });
};
}]);
shop.controller('Categories', ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
$scope.categories = [
{ name: 'games', id: 1 }, { name: 'films', id: 2 }
]
$rootScope.category_id = '-1';
$scope.select = function (id) {
$rootScope.category_id = id;
// Need to run an update of Product controller
}
}]);
When a user selects the category by clicking on it, I need to update products list with new products (filtered by selected category) that I received from a server. And the question is How to run update function of Products controller in Categories controller?
I know about easy-way with event broadcastings, but it is not the best solution.

Related

Multiple $http.get operatios and save the information in one $scope variable

I need to do four $http.get call and I need to send returned $scope variable to the one HTML to print all the information. In the moment I have the next code in JS:
(function (ng) {
var mod = ng.module("serviciosAdminModule");
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/hoteles").then(function (response) {
$scope.serviciosHotelesRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/paseos").then(function (response) {
$scope.serviciosPaseosRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/aseos").then(function (response) {
$scope.serviciosAseosRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/entrenamientos").then(function (response) {
$scope.serviciosEntrenamientosRecords = response.data;
});
}]);
})(window.angular);
In the HTML I have the next:
<tr ng-repeat="servicio in serviciosAdminRecords">
<td id="{{$index}}-id" class="parrafoscards" style="font-size: 16px">
<a ui-sref="servicioAdminDetail({servicioId: servicio.id})">{{servicio.id}}</a>
</td>...
In the HTML I ask for serviciosAdminRecords that is the $scope variable where I want to put all the .get data
You probably need to chain the promises in order to add all the responses together into the one array. Get rid of all the different controllers - they will have separate scopes - and just have the one controller, making sure it is being used in the view by using ng-controller='serviciosAdminCtrl' as an attribute in your view.
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$scope.serviciosAseosRecords = [];
$http.get("api/hoteles").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/paseos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/aseos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/entrenamientos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
});
});
});
});
}]);
If your response.data is an array of object then initialize serviciosPaseosRecords as array.
$scope.serviciosHotelesRecords = [];
instead of assigning response.data to serviciosPaseosRecords
$scope.serviciosAseosRecords = response.data
Concat response.data with existing serviciosAseosRecords array.
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data)

Share value between views in AngularJS

I have apage with 3 options and each option represent a group of permissions. I have the groupName in my view permissionsConfig but when I edit one group I lose the name of the group and i need the name to make a request to my rest api.
organizationsController.js
app.controller('OrganizationsPermissionsSettingsController',['$rootScope', '$scope', '$modal', 'HelperService', 'AuthService', '$state', '$http', function ($rootScope, $scope, $modal, HelperService, AuthService, $state, $http) {
var controllerScope = $scope;
controllerScope.organizationGroups = [];
$http.get('/api/organization_permissions_groups').success(function (data) {
controllerScope.organizationGroups = data;
});
controllerScope.openOrganizationPermissionsSettings = function (organizationId) {
$state.go('app.organizationPermissionsSettings');
};
var groupId = "";
document.addEventListener("DOMContentLoaded", function(event) {
if(document.getElementById("permissionGroupName").innerHTML!=null){
groupName=document.getElementById("permissionGroupName").innerHTML;
console.log("groupName ",groupName);
$http.get('/api/organization_permissions_groups/getId'+groupName).success(function (data) {
if(data != undefined && data != null){
groupId=data;
console.log("controllerScope.id ",groupId);
}
});
}
});
$scope.navigateToGraphs = function() {
$state.go('app.organizationGraphs', { groupId: groupId });
// then get parameter groupId
$state.params.groupId;
}
$scope.navigateToViews = function() {
$state.go('app.organizationViews', { groupId: groupId });
// then get parameter groupId
$state.params.groupId;
}
}]);
app.controller('OrganizationGraphsController',['$rootScope', '$scope', 'HelperService', '$http', '$stateParams', function ($rootScope, $scope, HelperService, $http, $stateParams) {
var controllerScope = $scope;
controllerScope.graphData = {};
$http.get('/api/organization_permissions_groups/graphs/'+$stateParams.groupId).success(function (data) {
controllerScope.graphData = data.graphs;
});
controllerScope.saveOptions = function () {
$http.put('/api/organization_permissions_groups/graphs/'+$stateParams.groupId, controllerScope.graphData).then(function (response) {
}, function () { });
HelperService.editItem(id, controllerScope.graphData, null, 'Graphs', '/api/organization_permissions_groups/graphs/');
}
$scope.cancel = function () {
$modalInstance.dismiss();
};
}
]);
organizationPermissionsConfigView.html
here I have <td id="permissionGroupName">{{organizationGroup.group_name}}</td> which retrive my permission group name.
I have 3 groups at the moment and with the group name i make a rest api request to get the id and with that id i can make updates on the permission group understand?

AngularJS expected information not displaying

I am working on a mobile application that gets a list of jobs from the server (WEBAPI) and populates the proper fields. When the user clicks on the job name, the application goes to a details page, where the job information needs to show again.
I am having issues getting the information to show.
Here is the index:
.state('jobs',{
abstract: true,
url: '/jobs',
templateUrl: 'modules/jobs/views/jobs.html',
controller: ['$scope', '$state', '$stateParams', 'jobs', function($scope, $state, $stateParams, jobs) {
jobs.getData()
.then(function(jobs) {
$scope.jobs = jobs;
});
}]
})
// Jobs > List
.state('jobs.list', {
url: '',
title: 'All Jobs',
templateUrl: 'modules/jobs/views/jobs.list.html'
})
// Jobs > Detail
.state('jobs.detail', {
url: '/{JobId:[0-9]{1,4}}',
title: 'Job Details',
views: {
'details': {
templateUrl: 'modules/jobs/views/jobs.detail.html',
controller: ['$scope', '$state', '$stateParams', 'utils', function($scope, $state, $stateParams, utils) {
$scope.job = utils.findById($scope.jobs, $stateParams.JobId);
$scope.edit = function(){
$state.go('.edit', $stateParams);
};
}]
},
'': {
templateUrl: 'modules/jobs/views/jobs.materials.html',
controller: ['$scope', 'materials', '$stateParams', function($scope, materials, $stateParams) {
materials.getDataById($stateParams.JobId)
.then(function(materials) {
$scope.materials = materials;
});
$scope.subHeader = 'Bulk Sack Materials';
}]
}
}
})
Here is the Service:
app.factory('jobs', ['$resource', '$q', '$http', 'localStorageService', function($resource, $q, $http, localStorageService) {
localStorageService.set('SessionId', 'A00DB328-7F9C-4517-AD5D-8EAA16FBBC8F');
var SessionId = localStorageService.get('SessionId');
return {
getData: function() {
var deferred = $q.defer();
$http.get(baseUrl + 'Job/GetJobs?SessionId=' + SessionId, {
cache: true
}).success(function(jobs) {
deferred.resolve(jobs);
});
return deferred.promise;
}
};
}]);
app.factory('materials', ['$resource', '$q', '$http', 'localStorageService', function($resource, $q, $http, localStorageService) {
var SessionId = localStorageService.get('SessionId');
return {
getDataById: function(id) {
var deferred = $q.defer();
$http.get(baseUrl + 'Material/GetMaterials/' + id + '?SessionId=' + SessionId, {
cached: 'true'
}).success(function(materials) {
deferred.resolve(materials);
});
return deferred.promise;
}
};
}]);
And here is the utils service:
app.factory('utils', function() {
return {
findById: function findById(a, id) {
for (var i = 0; i < a.length; i++) {
if(a[i].id === id) {
return a[i];
}
}
return null;
}
};
});
Here is the HTML for the job.list:
<div class="list-group">
<a class="list-group-item" ng-repeat="job in jobs" ui-sref="jobs.detail({ JobId: job.JobId })">
<dl>
<dt>{{job.Name}}</dt>
<dd>{{job.Location}}</dd>
</dl>
Some insight on how to get this to work would be awesome.
Thank You-
If I have inferred your goal correctly, you're issue is on the following line:
$scope.job = utils.findById($scope.jobs, $stateParams.JobId);
$scope.jobs will not exist like you expect it to. The jobs object was created in the list view's controller's scope, not the details view's controller. You'll want to do something like you have in the '' controller
JobService.getJobById($stateParams.JobId).then(function(data) {
$scope.job = data;
});

Angular js display name based on selected item and url path

I am starting out on the angular seed. I have a json file that displays items like the below.
{
"id":"1",
"name":"Spain",
"abbrev":"esp"
}
When I click on a country in the list I want to the display the details such as the name for this item.
I have this working as shown below.
/* app.js */
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', ['ngRoute','myApp.controllers','myApp.services'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'templates/view1.html',
controller: 'CountryCtrl'
});
}])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/:name', {
templateUrl: 'templates/view2.html',
controller: 'CountryCtrl'
});
}])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/'});
}]);
/* services.js */
angular.module('myApp.services', [])
.factory('Countries', ['$http', function($http) {
var Countries = {};
Countries.name = '';
Countries.listCountries = function () {
return $http.get('../api/countries');
},
Countries.ChangeName = function (value) {
Countries.name = value;
}
return Countries;
}]);
/* controllers.js */
angular.module('myApp.controllers', [])
.controller('CountryCtrl', ['$scope', 'Countries', '$location', function($scope, Countries,$location) {
listCountries();
function listCountries() {Countries.listCountries()
.success(function (data, status, headers, config) {
$scope.countries = data.countries;
})
.error(function(data, status, headers, config) {
$scope.status = 'Unable to load data: ' + error.message;
});
}
$scope.name = Countries.name;
$scope.changeView = function(countryName,indx){
$location.path(countryName);
$scope.name = Countries.ChangeName(countryName);
}
}]);
/* templates/view1.html */
<ul>
<li ng-repeat="country in countries">
<div ng-click="changeView(country.name,$index)">{{country.name}}</div>
</li>
</ul>
/* templates/view2.html */
{{name}}
What I can't get to work is that if I go to http://www.example.com/app/#/ then navigate to spain in the list then I get taken to http://www.example.com/app/#/esp and {{name}} gets outputted as esp.
However if I navigate straight to http://www.example.com/app/#/esp without first clicking on spain in the list I get no value in my $scope.name
How can I achieve this?
I want the name to also be set based on the location path if it is available.
I know that $location.$$path will get me /esp however I don't really think this is the best idea to use this incase the url builds out to something bigger eg http://www.example.com/app/#/esp/events
can I some how access the index or id of the item so that I can then access the data like
{{countries[0].name}}
where 0 is id of esp - 1.
What is the best approach?
Mate, there are a couple of issues with your app.
Your service retains "state" although is only used to retrieve information
You're using the same controller to 2 different views (bad practice)
$scope.status = 'Unable to load data: ' + error.message; --> Error is not defined
There are a couple of js errors too, like strayed commas and stuff
Anyways, here's a revised version of your code. Fiddle
// Instantiate your main module
var myApp = angular.module('myApp', ['ngRoute']);
// Router config
myApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'templates/view1.html',
controller: 'CountryListCtrl'
})
.when('/:id', {
templateUrl: 'templates/view2.html',
controller: 'CountryCtrl'
})
}
]);
// Your Factory. Now returns a promise of the data.
myApp.factory('Countries', ['$q',
function($q) {
var countriesList = [];
// perform the ajax call (this is a mock)
var getCountriesList = function() {
// Mock return json
var contriesListMock = [{
"id": "0",
"name": "Portugal",
"abbrev": "pt"
}, {
"id": "1",
"name": "Spain",
"abbrev": "esp"
}, {
"id": "2",
"name": "Andora",
"abbrev": "an"
}];
var deferred = $q.defer();
if (countriesList.length == 0) {
setTimeout(function() {
deferred.resolve(contriesListMock, 200, '');
countriesList = contriesListMock;
}, 1000);
} else {
deferred.resolve(countriesList, 200, '');
}
return deferred.promise;
}
var getCountry = function(id) {
var deferred = $q.defer();
if (countriesList.length == 0) {
getCountriesList().then(
function() {
deferred.resolve(countriesList[id], 200, '');
},
function() {
deferred.reject('failed to load countries', 400, '');
}
);
} else {
deferred.resolve(countriesList[id], 200, '');
}
return deferred.promise;
}
return {
getList: getCountriesList,
getCountry: getCountry
};
}
]);
//Controller of home page (pretty straightforward)
myApp.controller('CountryListCtrl', ['$scope', 'Countries',
function($scope, Countries) {
$scope.title = 'Countries List';
$scope.countries = [];
$scope.status = '';
Countries.getList().then(
function(data, status, headers) { //success
$scope.countries = data;
},
function(data, status, headers) { //error
$scope.status = 'Unable to load data:';
}
);
}
]);
// controller of Country page
// Notice how we use $routeParams to grab the "id" of our country from the URL
// And use our service to look for the actual country by its ID.
myApp.controller('CountryCtrl', ['$scope', '$routeParams', 'Countries',
function($scope, $routeParams, Countries) {
$scope.country = {
id: '',
name: '',
abbrev: ''
};
var id = $routeParams.id;
Countries.getCountry(id).then(
function(data, status, hd) {
console.log(data);
$scope.country = data;
},
function(data, status, hd) {
console.log(data);
}
);
}
]);
In your "CountryCtrl", if you include $routeParams and use $routeParams.tlaname, you will have access to the tlaname. You can then use that to initialize your data.

Dynamic injection angularjs?

i am using one of the basic concept of angularjs that child controller inherit from parent controller. so i have writen the following code :
var editChannelCtrl = function ($scope, $route, $location, youtube) {
$scope.loading = false;
$scope.saved = false;
$scope.errors = [];
if (angular.isDefined($route.current.params.id)) {
$scope.isOldChannel = true;
$scope.isNewChannel = false;
} else {
$scope.isNewChannel = true;
$scope.isOldChannel = false;
}
};
editChannelCtrl.$inject = ['$scope', '$route', '$location', 'youtube'];
editChannelCtrl.resolve = {
channel: ['ServiceChannel' , function (ServiceChannel) {
return ServiceChannel.ChannelLoader();
}]
};
var oldChannelCtrl = function ($scope, $location, channel) {
$scope.channel = channel;
};
oldChannelCtrl.$inject = ['$scope' , '$location', 'channel'];
var newChannelCtrl = function ($scope, $location, Channel) {
$scope.channel = {
id: null,
version: 1
};
};
newChannelCtrl.$inject = ['$scope' , '$location', 'Channel'];
and for routes what i do , that i resolve the channel that load the channel for the edit form with the following code.
.when('/admin/refactor/channel/edit/:id', {
controller: editChannelCtrl,
templateUrl: '/admin/assets/views/channelForm.html',
resolve: editChannelCtrl.resolve
})
.when('/admin/refactor/channel/new', {
controller: editChannelCtrl,
templateUrl: '/admin/assets/views/channelForm.html'
})
but i don't know why angularjs don't figure how to inject channel to oldChannelCtrl ?

Categories

Resources