I am new to AngularJS and I'm facing these issues :
I want to have a list of items (movies) and when I click on the image or on the title I want the path to be like #/movie/id. For that I tried using ngRoute and also tried path but I have faced errors in both, can you guide me which one is suitable for my case and how can I use it?
As you can see in the HTML code, I am trying to draw a search box but right now when the API runs and returns data the whole content of the ng-app is being replaced with the movie list, should I create a new scope for just the content I want to change, if so how and where?
Here is my code:
var movies = angular.module("movies", []);
movies.controller('movieController', function ($scope, $http) {
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit : 16,
country : 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.movies = data.movies;
});
});
//added ngroute
var app = angular.module('movies', ['ngRoute']);
app.config(
function($routeProvider) {
$routeProvider.
when('/', {templateUrl:'/'}).
when('/movie/:id',
{
controller:UserView,
templateUrl: function(params){ return '/moviessssssss/' + params.id; }
}
).
otherwise({redirectTo:'/'});
}
);
app.controller('UserView', function($scope) {
$scope.movies = 'hereeeeeee!';
});
<html ng-app="movies">
<head>
<link rel="stylesheet" hrf="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
</head>
<body>
<div class="ng-scope">
Search : <input type="text" placeholder="filter for..." >
</div>
<div ng-view>
{{ message }}
<table ng-controller="movieController" class="ng-cloak">
<tr ng-repeat="movie in movies">
<td><a ng-href="#movie" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="#movie" > {{ movie.title }} </a></td>
</tr>
</table>
</div>
For getting the links:
ng-href="{{'/#/movie/'+movie.id}}"
Then for getting the filter to work,
Put ng-model to your search box. And in your ng-repeat add | filter: ng-modelname
var movies = angular.module("movies", []);
movies.controller('movieController', function ($scope, $http) {
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit : 16,
country : 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
})
.success(function (data) {
$scope.movies = data.movies;
console.log($scope.movies);
});
});
<html ng-app="movies">
<head>
<link rel="stylesheet" hrf="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
</head>
<body>
<div class="ng-scope">
Search : <input type="text" placeholder="filter for..." ng-model="search">
</div>
<div ng-view>
{{ message }}
<table ng-controller="movieController" class="ng-cloak">
<tr ng-repeat="movie in movies | filter:search">
<td><a ng-href="{{'/#/movie/'+movie.id}}" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="{{'/#/movie/'+movie.id}}" > {{ movie.title }} </a></td>
</tr>
</table>
</div>
Click Here to see a live plunker example.
in my example, i used bootstrap. remove if irrelevant
there is a TODO in my plunker - the server side movie filtering (when you type a something in the search field). you need to read more about it in developer.rottentomatoes.com
This is the routing configuration i would define:
movies.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/movies', {
templateUrl: 'movies.html',
controller: 'MoviesController',
resolve: {
movies: function($http) {
return $http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit: 16,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK'
}
});
}
}
})
.when('/movies/:id', {
templateUrl: 'movie.html',
controller: 'MovieController',
resolve: {
movie: function($http, $route) {
var id = $route.current.params.id;
return $http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/movies/' + id + '.json', {
params: {
limit: 1,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK',
q: id
}
});
}
}
})
.otherwise({
redirectTo: '/movies'
});
});
/movies - a list of all movies/movies/<movie id> - a specific details about the movieNOTE - i used resolve to pre-fetch the json data (this is optional)
this is the main html code of your
<!DOCTYPE html>
<html ng-app="movies">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="app.js"></script>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
the view of the movie list.
we get the specific movie redirect by <a ng-href="#/movies/{{movie.id}}">
<input class="form-control" type="text" placeholder="Search ..." ng-model="search" >
<hr>
<table>
<tr ng-repeat="movie in movies | filter:search">
<td><a ng-href="#/movies/{{movie.id}}" ><img ng-src="{{ movie.posters.thumbnail}}"/></a></td>
<td><a ng-href="#/movies/{{movie.id}}"> {{ movie.title }} </a></td>
</tr>
</table>
the view of the specific movie
<img class="img-responsive" ng-src="{{ movie.posters.detailed}}"/>
<h3>{{movie.title}} <small>{{movie.year}}</small></h3>
<p>{{movie.synopsis}}</p>
<hr>
<a class="btn btn-default" href="#/movies">Back</a>
<hr>
<pre>{{movie | json}}</pre>
the controller attached to the movies.html view
the $scope.$watch('search', is required to query the server for each input change you make. it's currently not working properly; rottentomatoes.com ignoring the q param. you need to read more about it in developer.rottentomatoes.com
movies.controller('MoviesController', function($scope, $http, movies) {
$scope.search = '';
$scope.$watch('search', function(newValue) {
// TODO: you need to request again the movie list from the server.
// Read more about the API here:
// http://developer.rottentomatoes.com/docs/read/json/v10/Movies_Search
$http.jsonp('http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json', {
params: {
limit: 16,
country: 'us',
apikey: 'rssd8z7pfw5t4nyd3cpszzzm',
callback: 'JSON_CALLBACK',
q: newValue
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.success(function(data) {
console.log(data);
$scope.movies = data.movies;
});
});
$scope.movies = movies.data.movies;
});
the controller attached to the movie.html view
movies.controller('MovieController', function($scope, movie) {
$scope.movie = movie.data;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With