Unable to route non existing paths in Angularjs - angularjs

I am unable to route the path code/:code in my website. I receive the following error:
Firefox can't find the file at /C:/Code/dola/mobileweb/app/code/123
default.htm is located in the app folder.
I am using the mobileangularui framework. I have the following routes declared (among others):
app.config(function ($routeProvider) {
$routeProvider.when('/', { templateUrl: 'codeview.htm', reloadOnSearch: false });
$routeProvider.when('/code/:code', { templateUrl: 'codeview.htm', reloadOnSearch: false });
});
Everything works fine, except when I try e.g. code/12345.
This route is intended for a call from outside, e.g. www.mywebsite.com/code/12345.

I see two issues. First is re-declaring the $routeProvider unnecessarily. The second is you don't have an "otherwise" clause to catch everything you aren't already.
Also, not an error, but good practice to follow; you are missing a controller and controllerAs explicit directive for each entry. Try this:
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'codeview.htm'
, controller: 'HomeController'
, controllerAs: 'vm'
, reloadOnSearch: false
})
.otherwise({
redirectTo: '/'
})
});
This was based on the assumption that '/code/:code' is not its own page. The option is easy to add/change if this is not the case, following the above model.
Hope this helps.
-C§
-edit-
It looks as though the best way to do this (as with what I've done in my current project for such needs) is to store the code into a global (model) variable and call the redirect using $location.path('/');. Something like the below would be part of the click-function:
DataService.code = vm.code; //the code value selected
$location.path('/');
And the resulting page would have as part of its initialization routine:
vm.code = DataService.code; //retrieves the code from memory
//and uses it to populate the page appropriately
I'm unfamiliar with how to specify a URL and have it read what page it should populate based on the trailer, aside from using PHP to catch the URL extension with the index and a $_GET redirection process. I know this can be achieved using AJAX or a Jquery catch, but I'm still somewhat new to JavaScript as a whole and not sure what the process would look like.
Alternatively, you could designate a page for each possible code (ex: 12345.html || 12345.php).
Hope this also helps.
-C§

Related

From 1 to 3 controllers in Angular

I'm new to angularJS so I'm still learning the "angular way" of doing things and therefore seek for advice.
I started building my login/register/forgotten_password views which now work perfectly fine. So the routing looks basically like this:
mainApp.config(function ($routeProvider) {
$routeProvider
.when('/login',
{
controller: 'loginCtrl',
templateUrl: 'views/login.html'
})
.when('/register',
{
controller: 'registerCtrl',
templateUrl: 'views/register.html'
})
.when('/dashboard',
{
controller: 'dashboardCtrl',
templateUrl: 'views/dashboard.html'
})
})
Now here's the problem and/or question I have :
After a successful login, you get redirected to the dashboard which gets loaded into ng-view. The dashboard is indeed the view but there should be more controllers and templates once you enter the app (sidebar, topbar, chat...).
How would you approach this ?
I also have a globalCtrl on the html element to handle other things, just in case that information might be helpful in any way.
You shouldn't think in controllers anymore. Rather think in "components". There are lots of articles on the internet on how to learn this (better) approach. Here is one to start: Refactoring Angular Apps to Component Style
tl;dr; Create a component (element directive) for every section/part of your view. In your case a <dashboard>, <sidebar>, <topbar>, ...
You can (and should) route to components! See this issue for more information. Here is a "real life" example on how to achieve this: https://github.com/ui-router/sample-app-ng1
This is the con giving of using $routeProvider in Angular JS. When you use a $routeProvider to define routes in angular JS, a single route can only point to a single view and there is no concept of nested views using $routeProvider.
And when you talk about having more than one template inside the view, you are talking about having nested views inside a single view. Unfortunately Angular's $routeProvider doesn't provide that. But now comes the ui-router, which replace the concept of route with states. You can define multiple sub states in a state and each sub state can point to different template. Look at the following link and follow simple steps to power up views and nested views in your app.
ui-router

using ui.router to dynamic load pages

I'm a newbie in AngularJS, and I was using ui.router.
What I am trying to do is load html from different portals, like:
/s3/home
/goo/home
/gle/home
All prefix like s3, goo, gle are from backend, I have to get it first then load my pages, any idea for this, any way to put a variable in relative path, like
/{{portal}}/home
Mockup for expression:
angular.module('app')
.config(function ($stateProvider) {
$stateProvider
.state('{{portal}}.home', { //portal from backend
url: '/',
views: {
'content#': {
templateUrl: 'scripts/app/{{portal}}/home.html', //portal from backend
controller: 'MainController'
}
}
});
})
Find a way to do it, dynamic templateURL will do the same thing
http://fredparke.com/blog/angularjs-directive-dynamic-template
I want to use it in Javascript, is it possible
No i'm afraid not. Use Curly braces to bind expressions to elements in your html. I think you need to rethink more fundamentally your application and why you want to have "variable" template urls in such a way. Try and read up on REST as that's probably what you want to have for your backend. The frontend can then parameterise requests via url/query parameters

AngularJS route with trailing slash failing

I have a route that looks like and this and works:
when('/videos', {
templateUrl: 'partials/partial1',
controller: 'MyCtrl1'
}).
However, if I add a named group to the when:
when('/videos/:video_id', {
templateUrl: 'partials/partial1',
controller: 'MyCtrl1'
}).
it does not work when I try to visit videos/1 in the browser.
I get a bunch of errors in the console, along the lines of:
Uncaught SyntaxError: Unexpected token <
What's strange is that I also get an error that says
Resource interpreted as Stylesheet but transferred with MIME type text/html:
and the console says that is coming from a file named:
video_id:13
It seems like video_id is being interpreted as a file of its own?
I was under the impression that you could only do this with route names, and not with template names. Whenever you use : to designate a route parameter, it gets stored in $routeParams; however, I don't think there is an analogous service for use with template names. If so, the errors make sense.
Keep in mind that the route paths are the outward-facing paths seen in the URL. You will not see the template names in this way; the point of this code is to connect them. There is probably a way to restructure your application so that you can do what you want but also only have one partial per route, as I think is the best practice.
You're probably getting that error because your server is responding with a 404 or some other unexpected response. According to the $routeProvider documentation you can't even use : to specify a route parameter for the templateUrl but you can use a function
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
so then you can do
var partial1UrlBuilder = function(routeParams) {
return 'partials/partial1/' + routeParams.id;
};
...
when('/view1', {
templateUrl: partial1UrlBuilder,
controller: 'MyCtrl1'
}).
when('/videos/:video_id', {
templateUrl: '/partials/partial1',
controller: 'MyCtrl1'
})
I too faced same problem , prefixing slash before partials solved the issue.

How to Pass Variables When Using $routeProvider

I'm using $routeProvider to create a one page app where users press continue to go to the next step. It is important to pass variables to the next page whenever a user clicks continue so I followed some advice and created my own service which has persistent variables. This all works great except that I can only get variables from the service, I don't know how to update the variables. Here is my code:
myApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/pick_categories', {
templateUrl: '/pick_categories.html',
controller: 'MeetupDataCtrl'
}).
when('/pick_times', {
templateUrl: '/pick_times.html',
controller: 'MeetupDataCtrl'
}).
when('/events', {
templateUrl: '/events.html',
controller: 'MeetupDataCtrl'
}).
otherwise({
redirectTo: '/pick_categories'
});
}]);
myApp.service("meetupService", function(){
this.checked_categories = [];
});
myApp.controller('MeetupDataCtrl', ['$scope', '$http', '$location', '$resource', 'meetupService', function MeetupDataCtrl($scope, $http, $location, $resource, meetupService) {
$scope.checked_categories = meetupService.checked_categories;
}]);
Then in the view I have checked_categories bound to an input field.
I know the problem is that I'm getting the service's variables on init, but I'm not updating the service's variables from the scope after I change routes. Any ideas on how I could do this? (or if there are other best practices)
You could in fact change the service properties directly ... :
meetupService.checked_categories.push({ something: 'something'});
... but it's better to encapsulate the state properties of a service so you can do something like the following from your controller:
meetupService.addCategory('theCheckedCategory');
Do mind that services are singletons in Angular; there will be only one meetupService in your Angular application. This means that once the user has modified the checked_categories array somehow they will have that some array until they refresh/reload your website.
Also note that passing state information via url arguments is in most cases not necessary when building a single page app (which Angular is).
It sounds like your trying to build a wizard and if I'm guessing right you don't need anything of the above. Wizards are actually quite easy to make in Angular because all the state information is kept, ... well as long as you want it to.
See this plunker for a simple wizard example.
Edit:
Oh, and if you really need to pass arguments to the route, you can do that with the builtin $location service.
// change the path
$location.path('/newValue')
// change the query string / url arguments
$location.search({myArg: 'value', myOtherArg: 'anotherValue'});

How to handle routeProvider, with GET api call that can be bookmarked?

Here is my route provider:
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: '/partials/search.html'}).
when('/about', {templateUrl: '/partials/about.html'}).
when('/services', {templateUrl: '/partials/services.html'})
//otherwise({redirectTo: '/'});
;
}])
I'm running searches on /partials/search.html. I want that the searches can be bookmarked. So I added this to the code where I receive the ajax response of my search:
$location.path(myGetQuery);
But, well, this triggers the routeProvider and it doesn't load any fragment and the view is left empty. With otherwise... redirect it will show the blank search fragment / url and my search query is gone.
I also tried something like this...
$routeProvider.
when('/', {templateUrl: '/partials/search.html'}).
when('/:pars', {templateUrl: '/partials/search.html'}).
when('/about', {templateUrl: '/partials/about.html'}).
when('/services', {templateUrl: '/partials/services.html'});
And well, thanks to /:pars, $location.path(myGetQuery); makes the page load with the correct url (with the query), but the fragment is still reloaded, and since I'm executing this after I get the response of the search, my result is gone.
What is the correct way to handle this?
You can use $location.search to change querystring values of the url. See the documentation here.
Basically, after your search is complete you do something like this, which will update the url to: ...?q=foobar.
$location.search({ q: 'foobar' });
In your case you might want to take the object you pass into your ajax query and pass that into search.
When you enter your route, you can use $location.search() to extract existing values (in case they have a url bookmarked) and then perform the search based on those.
Update
As per comment, you also need to update your route to include reloadOnSearch: false.

Resources