I would like to pass article id from url to factory but I can't get the value from $routeChangeSuccess callback.
myApp.controller('editCtrl', function($rootScope, $scope, getArticleById, $filter, $route, $routeParams) {
var article_id = $rootScope.$on('$routeChangeSuccess', function () {
return $routeParams.id;
});
getArticleById.get(article_id).then(function(data) {
$scope.articles = data;
});
});
myApp.factory('getArticleById', function($q, $http) {
return {
get: function(article_id) {
var deferred = $q.defer();
$http.get('/api/admin/article/edit/'+ article_id).success(function(result) {
deferred.resolve(result);
}).error(function(result) {
deferred.reject(result);
});
return deferred.promise;
}
}
});
$routeProvider
var myApp = angular.module('myApp',['ngRoute','ui.utils','ngSanitize','ui.tinymce'])
.config(function ($routeProvider, $locationProvider) {
//configure the routing rules here
$routeProvider.when('/admin/article/edit/:id', {
controller: 'editCtrl'
});
//routing DOESN'T work without html5Mode
$locationProvider.html5Mode(true);
}
);
Instead of creating a var named article_id in your controller, simply use the $routeParams.id to pass the value to factory.
getArticleById.get($routeParams.id).then(function(data) {
$scope.articles = data;
});
You can just update the articles in the $routeChangeSuccess callback.
myApp.controller('editCtrl', function($rootScope, $scope, getArticleById, $filter, $route, $routeParams) {
$rootScope.$on('$routeChangeSuccess', function () {
getArticleById.get($routeParams.id).then(function(data) {
$scope.articles = data;
});
});
});
This might cause problems when there is multiple route changes in quick successions. In which case you would need to do some more work.
Related
The URL I use to retreive a JSON for my app has a dynamic parameter (:id ). I'm not too sure how I can work with this, so that it passes the ID the user has chosen. Just need a bit of guidance.
app.factory('bookcategories', ['$http', function($http) {
return $http.get('http://52.41.65.211:8028/api/v1/categories/:id/books.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
Controller
app.controller('BookCategoryController', ['$scope', 'categories', '$routeParams', function($scope, categories, $routeParams) {
categories.success(function(data) {
$scope.detail = data.categories[$routeParams.bookId];
$scope.currentCategoryIndex = parseInt($routeParams.categoryId);
$scope.myCategoriesDetails = $scope.category;
});
}]);
app.js
...
.when('/categories/:categoryId', {
controller: 'BookCategoryController',
templateUrl: 'views/booksincategory.html'
})
...
HTML
<h3 class="title">{{book.title}}</h3>
You could achieve this with a little service like the following code example. A factory is a wrong choice here.
app.service('bookCategories', ['$http', function($http) {
this.get = function (id) {
return $http.get('http://52.41.65.211:8028/api/v1/categories/'+ id + '/books.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
};
}]);
And than use it like:
app.controller('MyCtrl', function(bookCategories) {
bookCategories.get(1).then(function (result) {
console.log(result);
});
});
I've got few controllers working with different templates:
curryApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'table_index.html',
controller: 'CurryListCtrl'
}).
when('/cities/:cityId/', {
templateUrl: 'template-total.html',
controller: 'CurryDetailCtrl'
}).
when('/cities/:cityId/mobile/', {
templateUrl: 'template-mobile.html',
controller: 'CurryMobileCtrl'
}).
when('/cities/:cityId/online/', {
templateUrl: 'template-online.html',
controller: 'CurryOnlineCtrl'
}).
All of theses controllers have $scope variable called cities
For example, the first one:
curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route',
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$http.get('json/cities.json').success(function (data) {
$scope.cities = data;
...
The second one:
curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route',
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$http.get('json/cities.json').success(function(data) {
$scope.cities = data;
...
Is it okay to have repeated $scope variables in different controllers?
How should I refactor the code in order to escape duplicates?
If cities are not going to change for every controller use services like below
Your service should look like below
app.service('myService',function($http,$q){
var cities=null;
this.getCities=function()
{
var deferred = $q.defer()
if(this.cities==null){
$http.get('json/cities.json')
.then((response) => {deferred.resolve(response);cities=response;})
.catch((error) => deferred.reject(error))
}
else { deferred.resolve(cities)}
return deferred.defer
})
});
Use the above service in the controller
app.controller('ctrl',function($scope,myService){
myService.getCities().then(function(data){ $scope.cities = data;})
})
You can create a factory:
.factory('citiesFactory', function($http) {
function getCities(){
// return promise from function
return $http.get("json/cities.json");
}
return {
getCities: getCities
}
});
then in your controller:
curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route', 'citiesFactory'
function($scope, $routeParams, $http, $route, citiesFactory) {
$scope.cityId = $routeParams.cityId;
citiesFactory.getCities().then(function(response){
$scope.cities = response.data;
});
...
You should do create a factory like this. Forgive the syntax, but you get the idea.
app.factory('Cities', function ($http) {
return {
'getData': function() {
$http.get('json/cities.json').success(function (data) {
return data;
}
.error(function(error){
return [];
}
}
};
}]);
and in your controller inject the factory and get the data
curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route', 'Cities'
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$scope.cities = Cities.getData();
...
If the cities json is common for all the controllers.
One option would be to move the common object used across controllers into rootscope refer.
Other option would be to store the cities json in the service itself read here.
I want to wait for an http response before exiting angular controller. I have written the following code. But id doesn't work as the controller still exits before the http call is returned. Can anyone help me out to fix this? Thanks in advance.
var app = angular.module('app', []);
app.factory('MyService', function ($http) {
return $http.get('/api/endpoint').then(function(res){
return res.data;
});
});
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.then(function(data){
$scope.myVarialbe = data;
})
}]);
I would write this as below.
'use strict';
(function () {
function MyService($http) {
function getService() {
var url = yourURL;
return $http({ method: 'GET', cache: false, url: url });
}
return {
getService: getService
};
}
angular.module('app')
.factory('MyService', MyService);
}());
controller code:
MyService.getService().then(function(response) {
});
You can use like this factory just return request response promise and in controller use .then on returned promise.
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);
Use $q is better.
Eg:
app.factory('MyService', ['$http', '$q', function($http, $q) {
return {
getData: function() {
var deferred = $q.defer();
$http.get('/api/endpoint')
.then( function(resp) {
deferred.resolve( resp.data );
});
return deferred.promise;
}
};
}]);
app.controller('MyController', ['$scope', 'MyService',function($scope, MyService){
MyService.getData().then(function(data){
$scope.myVarialbe = data;
})
}]);
since I've been staring at this problem for some days now, I'm kinda new at AngularJS, I thought maybe someone here could help me. So to my problem:
I get a Typeerror when i try to save a new topic on a forum I'm creating: My controller
module.controller('newTopicController', ['$scope', '$http', 'dataService', function ($scope, $http, $window, dataService) {
$scope.newTopic = {};
$scope.save = function () {
dataService.addTopic($scope.newTopic)
.then(function () {
$window.location = "/#";
},
function () {
alert("couldnt save topic");
});
};
}]);
And my factory:
module.factory("dataService", function ($http, $q) {
var _topics = [];
var _isInit = false;
var _isReady = function () {
return _isInit;
};
var _getTopics = function () {
var deferred = $q.defer();
$http.get("/api/topics?withReplies=true")
.then(function (result) {
angular.copy(result.data, _topics);
_isInit = true;
deferred.resolve();
},
function () {
deferred.reject();
});
return deferred.promise;
};
var _addTopic = function (newTopic) {
var deferred = $q.defer();
$http.post("/api/topics", newTopic)
.then(function (result) {
var createdTopic = result.data;
_topics.splice(0, 0, createdTopic);
deferred.resolve(createdTopic);
},
function () {
deferred.reject();
});
return deferred.promise;
};
return {
topics: _topics,
getTopics: _getTopics,
addTopic: _addTopic,
isReady: _isReady
};
});
So when i try to add a topic to the forum I just get "TypeError: Cannot read property 'addTopic' of undefined" in the controller, right where dataService.addTopic($scope.newTopic) is.
I also have another controller who also uses the factory, but that shouldnt be a problem right?
Thanks for your time.
This seems incorrect:
module.controller('newTopicController', ['$scope', '$http', 'dataService', function ($scope, $http, $window, dataService) {...}
Change it to:
module.controller('newTopicController', ['$scope', '$http', '$window', 'dataService', function ($scope, $http, $window, dataService) {...}
How can I call/access Controller method ($scope.some_function()) after finished Ajax request!
var app = angular.module('home', ['ngRoute']);
app.controller('IModalCtrl', function ($scope, $http, $route, $routeParams, $location) {
$scope.will_call_this = function() {
//
};
});
app.config(['$routeProvider', '$locationProvider', '$httpProvider',
function ($routeProvider, $locationProvider, $httpProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/news/:cat/:slug/:id', {
templateUrl: function (attr) {
return '/news/' + attr.cat + '/' + attr.slug + '/' + attr.id + '?ajax=1'
},
controller: 'IModalCtrl'
// IS ANY PROPERTY/METHOD HERE
// WHICH WILL ALLOW/ACCESS TO CONTROLLER PROPERTY
})
.otherwise('/');
}]);
In above, I want to call IModalCtrl's $scope.will_call_this() function after $routeProvider has finished the request. Just like jQuery ajax work.
jQuery Ajax e.g:
jQuery.ajax("example.php")
.done(function () {
alert("success");
// Need this functionality in AngulaJS
})
.fail(function () {
alert("error");
})
.always(function () {
alert("complete");
});
Please try with the following.
app.controller('IModalCtrl', function ($scope,$rootScope, $http, $route, $routeParams, $location) {
$scope.will_call_this = function() {
//
};
$rootScope.$on('$routeChangeSuccess', function (event, next, current) {
$scope.will_call_this();
});
});