Calling Routes from a js angular 1.5.8 file - javascript

I've my backend developed in Silex with various routes that I can fully access using localhost:8080/project/api/index.php/user (example of a route).
if i'm coding an http get(I use only one controller called mainController ) in a js file using angular 1.5.8, how can I make that when I enter angularsite/user
(user is the route, "/user"), it returns me the data and then show it on my index.html ?

You need to set your app routes to your mainController controller.
angular.module('YourProject', [
'YourModule',
'ngRoute'
])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/user', {
templateUrl: 'view.html',
controllerAs: 'mainCtrl',
controller: 'mainController '
});
$routeProvider.otherwise({
redirectTo: '/user'
});
}])
Now when the page loads the RouteProvider will finds the default path to user (default route) route and that will load your view and controller. The templateUrl contains the route to the template.

If you only want to load a partial page you can do something like this..
'use strict';
var App = angular.module('YourProject', ['ngRoute', 'AppControllers']);
App.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/user', {
templateUrl: 'user.html'
}).
otherwise({
redirectTo: '/path'
});
}]);
Since your question mentions an API if you are trying to just load some data you can call user API with something like this from your controller (provided that the url given is an API which accepts GET request and responds with JSON data)..
var AppControllers = angular.module('AppControllers', []);
AppControllers.controller('MainController', ['$scope','$http', function ($scope, $http) {
//Declare a function to fetch user data from API
$scope.user= function () {
var req = {
method: 'GET',
url: baseURL + 'project/api/index.php/user'
}
return $http(req).success(function (data,status,header) {
$scope.user = data;
}).error(function () {
console.log(error);
});
}
//Call the get user function
$scope.user();
}]);
And finally in your partial file (user.html) add the controller to bind it with the controller declared above.
<!doctype html>
<html ng-app="YourProject">
<body>
<head>
<title>User Page</title>
</head>
<div class="user-content" ng-controller="MainController">
</body>
</html>

Related

Angularjs infinate loop without #! in url

I am using AngularJS v1.6.5
When I navigate through the pages of the website normally the URL is in the form of:
https://mySite.co.uk/#!/login
However when I type in an address without the hash-bang the site goes into an infinite loop and the following message is displayed in the browser console output:
WARNING: Tried to load angular more than once.
My route provider looks like this
.config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
}).
//ALL ELSE
.otherwise({
redirectTo: '/'
});
I have an interceptor listening for HTTP error messages however this doesn't seem to be being called:
$httpProvider.interceptors.push(['$q', '$location', '$localStorage', function ($q, $location, $localStorage) {
return {
'responseError': function (response) {
if (response.status === 404) {
window.location = "/";
}
return $q.reject(response);
}
};
}]);
One solution I found is to use html5 mode to remove the #! from the URL, then the '.otherwise' route in the route provider catches any other requests.
$locationProvider.html5Mode(true);
Then in the index.html add:
<head>
<meta charset="utf-8">
<base href="/">
</head>

Using ngroute to redirect unauthorized users in Angular

I am making a web app using Angular for front-end.
If user whose role is teacher trying to access applicant's portal, I want to block them by showing 404.html template. I do not want to redirect the users to www.example.com/404 but rather just let them stay at where they are at www.example.com/teacher but render 404.html template.
I am not sure how I can achieve this using ngroute. Here is the code what I have in app.js:
app.config(['$routeProvider', '$locationProvider', 'CookieProvider',
function ($routeProvider, $locationProvider, CookieProvider) {
var cookieData = CookieProvider.$get().getCookieData();
$routeProvider.when('/applicant', {
templateUrl: '/front-end/public/views/Prescreening/review.html',
controller: 'ReviewCtrl',
resolve:{
"check":function($location, CookieService) {
var cookieData = CookieService.get();
if(cookieData["user_role"] == 'teacher'){
$location.path('/404')
}
}
}
}).when('/404', {
templateUrl: '/404.html'
}).otherwise({
templateUrl: '/404.html'
});
}]);
How can I render 404.thml without redirecting the user to /404 ?
Let's say you have a state like this.
.state('dashboard.users', {
url: '/users/:isAdmin',
templateUrl: 'modules/dashboard/templates/users.html',
controller: 'usersController',
})
Try this.
angular.module(...)
.config( ['$routeProvider', function($routeProvider) {...}] )
.run(function($rootScope, $location) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
// You can pass the user role to the params
// of the state and you will see that on the
// toParams call callback ex. {isAdmin:false}
if(!toParams.isAmin){
toState.templateUrl = "modules/404/templates/404.html";
}
});
})
})
UPDATE
The callback toState actually contains the following
url = url of the current state ex. /user
templateUrl = path to the template ex. path/to/something.html
controller = the controller name of the state ex. usersController
name = the state name ex. dashboard.user
When this line gets executed toState.templateUrl = "modules/404/templates/404.html"; The current template of your state which falls under the <div ui-view></div> will have the 404.html that you desire.
IMPORTANT
You must use ui.router and not ngRouter to make this implementation work.
After some efforts I got it working... Here are the different codes...
I have used bower so please replace with your paths..
Here is the plunk.. I got it working..
https://plnkr.co/edit/dK7n6PmhldJ1p0plWPp2?p=preview
index.js
var app = angular.module('myApp',['ngRoute']);
app.config(['$routeProvider',function ($routeProvider) {
$routeProvider
.when('/applicant', {
template: 'Applicant!',
controller: function($scope){
alert("Applicant Controller");
}
})
.when('/404', {
templateUrl: '404'
})
.otherwise({
templateUrl : '404.html'
});
}]);
index.html
<html>
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src = "index.js"></script>
</head>
<body ng-app="myApp">
<ng-view></ng-view>
</body>
</html>
404.html
<h1>404 page</h1>

AngularJS app making multiple request to the backend

I have an Angular app which makes some calls (POST and GET for now) to a backend service (powered by node.js with a REST interface). While developing the app itself I noticed it makes two requests to the backend each time a button is pressed or a page is loaded. Curiously everything works but each time I press some button the backend gets two requests. I am not using any fancy package only ngRoute, ngResource and routeStyles for css partials. Anybody has an idea of what could be the reason why the app behaves like that?
I actually found another question similar to this one but the OP there was using express aside of Angular and there is no answer...
EDIT added some code.
in app.js:
'use strict';
var cacheBustSuffix = Date.now();
angular.module('myApp', ['myApp.controllers', 'myApp.services', 'myApp.filters', 'ngRoute', 'ngResource', 'routeStyles'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$locationProvider
.html5Mode({enabled: true,
requireBase: false})
.hashPrefix('!');
$routeProvider
.when('/', {redirectTo: '/myApp'})
.when('/myApp', {
templateUrl: '/partials/home.html?cache-bust=' + cacheBustSuffix,
controller: 'ctrlHome'
})
.when('/myApp/search', {
templateUrl: '/partials/search.html?cache-bust=' + cacheBustSuffix,
controller: 'ctrlSearch'
})
.when('/myApp/list/', {
templateUrl: '/partials/list.html?cache-bust=' + cacheBustSuffix,
controller: 'ctrlList'
})
// a bunch of other redirections
.otherwise({
templateUrl: '/partials/404.html?cache-bust=' + cacheBustSuffix,
controller: 'ctrl404'});
}]);
from services.js:
'use strict';
var app = angular.module('myApp.services', ['ngResource']).
factory('List', function ($resource) {
return $resource(WSROOT + '/search', {}, {get: {method: 'GET', isArray: false}});
});
from controllers.js, one controller that makes multiple requests
var controllers = angular.module('myApp.controllers', []);
var ctrlList = controllers.controller('ctrlList', function ($scope, $window, List) {
$window.document.title = 'myApp - List';
List.get({}, function (data) {
// $scope.res is an array of objects
$scope.res = data.response;
$scope.nitems = data.response.length;
});
});
ctrlList.$inject = ['$scope', 'List'];
And the network call when loading the index+home and navigating to some other page. As you can see, it first loads the index page, the scripts and styles listed there (not shown), then the home where I have a controller similar to the one above and suddenly two wild request to my web server:
Can we see your HTML files? I had this problem a while back. My solution was that by declaring a controller in the routing, and in the pages, a double post was created as each controller was loaded twice.
//Home
.state('tab.home', {
url: '/home',
views: {
'tab-home': {
templateUrl: 'templates/tab-home.html',
controller: 'HomeCtrl' // <-- This goes away
}
}
})

Can I call Route Provider service in Controller in angular js asp.net mvc

I am using controller in my Angularjs which gets question one by one from server and i want on specific condition this controller should call a routeprovider that should change my current view with templateUrl and put into a directive
my question is can i call route provider in controller rather than module
here is my CreateController
var CreateController = ['$scope', '$http', function ($scope, $http) {
$scope.model = {
};
................>
.................>
$scope.NextQuestion = function () {
$http.post('/Testing/NextQuestion', {
........................>
}).success(function (newdata) {
$scope.model = newdata;
var inccomplevel = $scope.model.servercomplevel;
if (qId == 10) {
here i need the code for routeProvider and directive please provide me help
}
......................>
}];
i did the route provider in app.js file there it works
here is the code for app.js when i do like this it works and when i shift the code of route provider
to the create controller in condition if qId == 10 there it does not work
var app = angular.module('app', ['ngRoute']);
app.controller('CreateController', CreateController);
app.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: 'Partials/TestCompleted.html',
controller: 'AppCtrl'
})
.otherwise({ redirectTo: '/' });
});
app.controller("AppCtrl",function ($scope) {
$scope.newmodel = {
}
});
Instead of trying to change the value of the templateUrl on the route, you should define another route. Then you can simply switch routes.
To change the route/view, you need update the path. You can do this using the $location service.
See AngularJS : How do I switch views from a controller function?

MEANJS: Check db for url and route to dynamic Angular state

Context
Users can register with a unique URL slug that identifies their page, e.g. 'http://example.com/slug'.
Current State
In my Express.js file, I successfully check my database to see if the slug exists on a user, then redirect the user from 'http://example.com/slug' to 'http://example.com/#!/slug' to take advantage of Angular's routing.
With Angular, however, I can't use $http or $location services in my router file (since it's taking place inside module.config...see this Stack Overflow explanation for more details).
Desire
Basically what I want to do is route the user to a 'default' view when a valid slug is found, or home if it's not. Any suggestions would be much appreciated.
For reference, my module.config code can be found here (note that the 'default' state I want to use is 'search'):
core.client.routes.js
'use strict';
// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// Redirect to home when route not found.
$urlRouterProvider.otherwise('/');
// Home state routing
$stateProvider.
state('home', {
url: '/',
templateUrl: 'modules/core/views/home.client.view.html'
}).
state('search', {
url: '/search',
templateUrl: 'modules/core/views/search.client.view.html'
});
}
]);
What I would like to do, is something like this...
'use strict';
// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider', '$http', '$location',
function($stateProvider, $urlRouterProvider, $http, $location) {
// Get current slug, assign to json.
var slug = $location.path();
var data = {
link: slug
};
// Check db for slug
$http.post('/my/post/route', data).success( function(response) {
// Found slug in db
}).error( function(response) {
// Route to home
$location.path('/');
});
// Home state routing
$stateProvider.
state('home', {
url: '/',
templateUrl: 'modules/core/views/home.client.view.html'
}).
state('search', {
// Set URL to slug
url: '/' + slug,
templateUrl: 'modules/core/views/search.client.view.html'
});
}
]);
To directly answer your question, what you want to do is use the routes "resolve" to check for the dependency and redirect to the appropriate view:
angular.module('app', ['ui.router','ngMockE2E'])
.run(function ($httpBackend) {
$httpBackend.whenGET(/api\/slugs\/.*/).respond(function (method, url) {
return url.match(/good$/) ? [200,{name: 'john doe'}] : [404,''];
});
})
.config(function ($stateProvider) {
$stateProvider
.state(
'search',
{
url: '/search?terms=:slug',
template: '<h1>Search: {{vm.terms}}</h1>',
controllerAs: 'vm',
controller: function ($stateParams) {
this.terms = $stateParams.slug;
}
}
)
.state(
'slug',
{
url: '/:slug',
template: '<h1>Slug: {{vm.user.name}}</h1>',
controllerAs: 'vm',
controller: function (user) {
this.user = user
},
resolve: {
user: function ($q, $http, $stateParams, $state) {
var defer = $q.defer();
$http.get('http://somewhere.com/api/slugs/' + $stateParams.slug)
.success(function (user) {
defer.resolve(user);
})
.error(function () {
defer.reject();
$state.go('search', {slug: $stateParams.slug});
});
return defer.promise;
}
}
}
);
});
<div ng-app="app">
<script data-require="angular.js#*" data-semver="1.3.6" src="https://code.angularjs.org/1.3.6/angular.js"></script>
<script data-require="ui-router#*" data-semver="0.2.13" src="//rawgit.com/angular-ui/ui-router/0.2.13/release/angular-ui-router.js"></script>
<script data-require="angular-mocks#*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular-mocks.js"></script>
<a ui-sref="slug({slug: 'good'})">Matched Route</a>
<a ui-sref="slug({slug: 'bad'})">Redirect Route</a>
<div ui-view></div>
</div>
But, there are a few things you may want to revisit in your example:
Is there a need to perform this check client side if you are already validating and redirecting server side via express?
You seem to be overloading the / route a bit, if home fails, it redirects to itself
You are grabbing slug from $location on app init, not when the view is routed to which could be post init, you need to grab it when ever you are routing to the view
You may want to consider using a GET request to fetch/read data for this request rather than using a POST which is intended generally for write operations (but thats a different story)

Categories