Reputation: 51
I've been doing a mini project using the TMDb API and AngularJS. My Angular routing part works, and i can load the movie details on click. The click on the homepage takes you to details view and the URL changes to movie/:id/:title
and now if the user clicks on another movie present in the details view, the relevant data for the newly clicked movie replaces the previous data. Now if i try going back using the browser the data of the previous movie is not loading up, but the URL shows the previous movie's title.
Along with this error, there's an other bug. When i try reloading the browser it causes 404 Error. If i turn html5Mode(true)
this occurs. If i disabled html5Mode
the page doesn't show relevant information, but shows me an empty template in the view. I'm just a beginner in AngularJS. I don't know how to fix this. I have mentioned the domain where i've hosted the website. I guess, looking at it would be easier to understand my problem. Hope someone out here could help me.
PROJECT URL: http://movie-buffs.xyz/
This is my routing code.
.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider){
$routeProvider
.when('/',{
templateUrl:'templates/movies.html'
})
.when('/movies/:id/:title',{
templateUrl:'templates/moviedetails.html'
})
.when('/search',{
templateUrl:'templates/search.html'
})
.when('/tv',{
templateUrl:'templates/tv.html'
})
.when('/tv/:id/:title',{
templateUrl:'templates/tvdetails.html'
})
.when('/celebs',{
templateUrl:'templates/celebs.html'
})
.when('/celebs/:id/:name',{
templateUrl:'templates/celebsdetails.html'
})
.when('/contact',{
templateUrl:'contact_us.html'
})
.otherwise({
redirectTo:'/'
});
$locationProvider.html5Mode(true);
}]);
Upvotes: 2
Views: 1240
Reputation: 5778
Solution 1
angularjs provides html5Mode, which makes your app use pushstate-based URL instead of hashtags. However this requires server side support, since the generated urls need to be rendered properly as well.
Simply copy index.html to 404.html, and add this to your app:
angular.module('app', []).config(function($locationProvider) {
$locationProvider.html5Mode(true);
});
Please find this link for more information
Solution 2
open index.html page and in head section add
<base href="/">
Your Angular code enable html5Mode
angular.module('main', []).config(['$locationProvider', function($locationProvider) {
...
$locationProvider.html5Mode(true);
...
});
After doing this, you need to create a .htaccess file on the root of your shared Apache server as your are using apache server add below code
Apache Server
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
IIS Server
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
That's it
Upvotes: 1
Reputation: 1931
This is how I do it. In my config.
.config(['$routeProvider', function ( $routeProvider) {
$locationProvider.html5Mode(false).hashPrefix('');
$routeProvider.otherwise({redirectTo: '/dashboard'});}]);
I divide the html with corresponding js in to folders ex:
/movie-details/movie-detail.html
/movie-details/movie-detail.js
My movie-details.js should look something like:
'use strict';
angular.module('myapp')
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/movies/:Id', {
templateUrl: 'movie-details/movie-detail.html',
controller: 'MovieDetails as vm'
});
}])
.controller('MovieDetails', function ($scope, $routeParams) {
var vm = this;
vm.movieId= $routeParams.Id;
});
In the html you wont need any Controller directive. Just:
{{vm.something}}
Upvotes: 0
Reputation: 1931
Nice page! Try out the html5 mode answer from Curiousdev. And I think you can make the routing simpler. You could change the routing from
('/movies/:id/:title')
to
('/movies/:id')
Here is an example on single movie on imdb:
They don't provide the title in the url either
Further: If you want to break down the problems in angular routing , remove all extra jquery scripts an so on. Make sure it works before you add the cool gui stuff
Upvotes: 0