AngularJS route provider - post request - javascript

How can I do a post request to a url using routeprovider? Provided sample code below
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/", {
templateUrl : "main.htm"
})
.when("/red", {
templateUrl : "red.htm"
})
.when("/green", {
templateUrl : "green.htm"
})
.when("/blue", {
templateUrl : "blue.htm"
});
});
</script>

You can use a resolve:
.when("/", {
templateUrl : "main.htm",
resolve: {
data: function($http) {
$http.post('/yourUrl', yourData)
.then(function(res) {
return res;
}, function(err) {
console.log(err);
return null;
})
}
}
})
And then in your controller,
.controller(function(data) {
console.log(data);
})
NOTE: This is not using routeProvider per se, because making REST calls is not what the routeProvider is for. Angular can do that only through the $http service. I am assuming that you just want to make a REST call from within your route definition.
Protip A better way of doing this would be to define a service in your module, and insert the module in the route resolve, rather than injecting $http directly. I've done that here only for brevity

Related

Prevent auto calling function in angularjs service

I am new to AngularJs and i have an issue that when i run my app, the factory function call twice time. I want to prevent by calling function from Factory function.
Here is my code:-
advisoryApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.html',
controller: 'mainCtrl'
})
.when('/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
.when('/contact', {
templateUrl: 'pages/contact.html',
controller: 'contactController'
});
});
advisoryApp.factory('HttpResponse', function ($http) {
return{
getHttpResponse: function (method, url, data) {
return $http({
url: url,
method: method,
data: data
})
}
});
advisoryApp.controller('mainCtrl', function ($scope, HttpResponse, $rootScope) {
$scope.allAdvisoryData = '';
var segment_id = 5;
var url = $rootScope.base_url + "web_service/call_listing/" + segment_id;
var data = 'segment_id=' + segment_id;
$scope.message = 'Everyone come and see how good I look!';
HttpResponse.getHttpResponse('POST', url, data).success(function (data) {
console.log(data);
});
});
Here is my output:-
Here api i.e POST http://localhost/advisory_mandi/web_service/call_listing/5 call twice but i want, it should call only one time.
Most common reason is that you initialise your controller twice.
Few options:
Controller initialised from router and from html with ng-controller
Application initialised twice. Maybe you call ng-app twice
Application bootstrapped from javascript and also from html

AngularJS: templateUrl is rendering before the controller is free

Below is the code which making some trouble
angular.module("cattle_feed_frontend", ['ngResource','ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/',
{
controller: 'FeedController',
templateUrl: 'templates/FeedList.html'
}).
otherwise({
redirectTo: '/'
});
}])
.controller('FeedController', function($scope,feeds_factory) {
$scope.feeds = feeds_factory.allFeeds();
})
.factory('feeds_factory',['$http', function($http){
return {
allFeeds : function(){
$http.get("http://localhost:3000/feeds").then(function(response)
{
return response.data;
});
}
}
}])
In controller feeds_factory.allFeeds() making http call to a 3rd party . now when i see my console . It shows that my template is rendered first and then my http is made . Why? and issue due to this behavior is that my template is rendered in which i made the ng-repeat which makes nothing because $scope.feeds is set after its rendering , as follows
<tr ng-repeat="feed in feeds">
<td>
{{feed.ingredient}}
</td>
<td>
{{feed.cost_kg}}
</td>
</tr>
Because $routeProvider doesn't know your controller is going to make a http request, it doesn't know to wait. To tell it you use the resolve property of a route:
$routeProvider.
when('/',
{
controller: 'FeedController',
templateUrl: 'templates/FeedList.html',
resolve: {
feeds: function(feeds_factory) {
return feeds_factory.allFeeds();
}
}
}).
otherwise({
redirectTo: '/'
});
Then return the promise from feeds_factory:
factory('feeds_factory',['$http', function($http){
return {
allFeeds : function(){
return $http.get("http://localhost:3000/feeds").then(function(response) {
return response.data;
});
}
}
}])
Then inject into the controller:
controller('FeedController', function($scope, feeds) {
$scope.feeds = feeds;
})
Most likely you need to change your code to this:
.controller('FeedController', function($scope,feeds_factory) {
feeds_factory.allFeeds()
.then(function(feeds) {
$scope.feeds = feeds;
});
})

Angular load route when ajax returns

How can I delay/defer a route/controller until an anonymous function returns? On app bootstrap, I default rootScope.me as guest account until it can check cookies for a logged in user.
I have a controller, testCtrl, that relies on rootScope.me data to load appropriate user data. The controller is fired before rootScope.me has a chance to be set to the user.
I know Angular has $q service for resolving promises, but am not sure how to apply this to routing.
angular
.module('DDE', [])
.run(['$rootScope', 'Me', function($rootScope, Me) {
$rootScope.me = {
username : 'Guest',
id : -1
};
if (Cookies.get('user_id') && Cookies.get('username')) {
Me.getProfile({user_id : Cookies.get('user_id')}).success(function (res) {
$rootScope.me = res;
}).error(function (err) {
console.log('Error: ', err);
});
}
}])
.config(['$routeProvider', '$httpProvider', '$authProvider',
$routeProvider.
when('/test', {
templateUrl: '/html/pages/test.html',
controller: 'testCtrl'
}).
.config(['$routeProvider', '$httpProvider', '$authProvider', '$stateProvider', '$urlRouterProvider',
function($routeProvider, $httpProvider, $authProvider, $stateProvider, $urlRouterProvider) {
//Cannot inject services like Me or $rootScope as I need
function loadProfile () {
Me.getProfile({user_id : Cookies.get('user_id')}).success(function (res) {
$rootScope.me = res;
}).error(function (err) {
console.log('Error: ', err);
});
}
$stateProvider.
state('test', {
url : '/test',
templateUrl: '/html/pages/test.html',
controller : 'testCtrl',
resolve : {
ProfileLoaded : function () {
return loadProfile();
}
}
});
edit: adding angular's ngRoute example.
You can look into ui-router's resolve. It basically waits for your promise to be resolved before loading/navigating to your state/route.
documentation
Each of the objects in resolve below must be resolved (via
deferred.resolve() if they are a promise) before the controller is
instantiated. Notice how each resolve object is injected as a
parameter into the controller.
Here's angular's ngRoute example from angular's documentation:
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
// I will cause a 1 second delay
delay: function($q, $timeout) {
var delay = $q.defer();
$timeout(delay.resolve, 1000);
return delay.promise;
}
}
})

AngularJS, How about multiple routes with different templates but the same controller?

i'm investigating if i can have what the title says.
Here's my thought.
Let's assume that i've got this routes:
.when('/', {
templateUrl : 'partials/homepage.html',
})
.when('/test', {
templateUrl : 'partials/test.html',
})
.when('/page/:pageID', {
templateUrl : 'partials/page.html',
})
.when('/page/single/:pageID', {
templateUrl : 'partials/page-single.html',
})
Until now i had the opportunity to add the templateUrl as also the controller details in the route and everything was working just fine.
Now the app is changed and there is only one controller with all the information needed and must remain one controller. And the routes will be something like that:
.when('/:templateName/:pageID', {
controller: 'myCtrl'
})
Can i set from the controller the template id by getting the templateName parameter? And if so how about the last route example /page/single/:pageID? How can i know that there is a second option in route?
I can take the templateName parameter and see it changing with the $routeChangeSuccess method but i cannot find any way to set the template on the fly.
Any ideas?
One solution could be the following one:
angular.module('myapp', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/:templateName/:pageId', {
templateUrl: function(urlattr){
return '/pages/' + urlattr.templateName + '.html';
},
controller: 'YourCtrl'
});
}
]);
From the AngularJs 1.3 Documentation:
templateUrl – {string|function()} – path or function that returns a path to an html template that should be used by ngView.
If templateUrl is a function, it will be called with the following parameters:
Array.<Object> - route parameters extracted from the current $location.path() by applying the current route
I would move your singleton logic from your controller to a service. Since you didn't provide much code below is an example to give you an idea how it could work.
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/homepage.html',
controller: 'SingleController'
})
.when('/test', {
templateUrl: 'partials/test.html',
controller: 'SingleController'
})
.when('/page/:pageId', {
templateUrl: 'partials/page.html',
controller: 'SingleController'
});
});
app.provider('appState', function() {
this.$get = [function() {
return {
data: {}
};
}];
});
app.controller('SingleController', function ($scope, appState) {
$scope.data = appState.data;
});
But if it must be a singleton controller you actually could use the ng-controller directive before your ng-view directive so it becomes a $rootScope like scope for all your views. After that just add empty function wrappers in your $routeProvider for the controllers.

How to make ng-view wait for XHR response?

I´m trying to make the ng-view wait for a xhr request. I have two controllers for a routed ng-view, the first one is loaded perfectly. But the other doesn't gets rendered well, because the xhr response happens after partial.html is downloaded. How do I avoid the partial.html request until that client get the xhr response?
You can see below the code for the route configuration:
var configuration = [
'$routeProvider',
'$locationProvider',
function(routeProvider, locationProvider) {
routeProvider.when('/', {
templateUrl: '/partials/hotelinfo.html',
controller: 'HotelInfo'
}).when('/service/dept/:id', {
templateUrl: '/partials/department.html',
controller: 'Department'
}).otherwise({
redirectTo: '/'
});
locationProvider.html5Mode(true);
}
];
Below you can see the controller configuration that gets the xhr response
<!-- language: lang-js -->
var Department = [
'$scope',
'$routeParams',
function (scope, routeParams) {
http.get('/service/dept/' + routParams.id).success(function (data) {
scope.data = data;
});
}
];
Instead of calling $http.get from your controller, call it from a resolve function on $routeProvider and inject it into the controller. That will cause Angular to not load your view until the promise from $http is resolved.
You can accomplish this using resolve in the routeProvider. It returns a promise. The view will not load until that promise is resolved. You can resolve that promise in your controller.
See http://docs.angularjs.org/api/ngRoute/provider/$routeProvider for more info.
var configuration = [
'$routeProvider',
'$locationProvider',
function(routeProvider, locationProvider) {
routeProvider.when('/', {
templateUrl: '/partials/hotelinfo.html',
controller: 'HotelInfo'
}).when('/service/dept/:id', {
template: '/partials/department.html',
controller: 'Department',
resolve: {
deferred: function($q) {
return $q.defer();
}
}
}).otherwise({
redirectTo: '/'
});
locationProvider.html5Mode(true);
}
];
var Department = [
'$scope',
'$routeParams',
'deferred',
function (scope, routeParams, deferred) {
http.get('/service/dept/' + routParams.id).success(function (data) {
scope.data = data;
deferred.resolve();
});
}
];

Categories

Resources