I'am trying to make simple web application using TMDB api but I'm having trouble with some request.
I'am successfully connecting to its api and getting all needed data and displaying it nicely. Problem is when i load my Homepage which has poster_path of movie, i get all posters nicely and displayed but in chrome dev tools I can see there is one more extra request sent (not sent by me... at least not on purpose) and its failing and wracking my app.
Chrome displays following for bad request:
GET file:///C:/Users/Ivan/Documents/testProject/fmdb-fjume-movie-database/app/%7B%7BimageBaseUrl%7D%7D/%7B%7Bmovie.poster_path%7D%7D net::ERR_FILE_NOT_FOUND
Status: failed
Initiator: other
Here's my code for getting information and html:
Home view
<div class="well main-frame">
<h1>MY MOVIE DATABASE</h1>
<div class="row row-centered">
<div class="col-sm-2 col-centered" style="text-align:center;" ng-repeat="movie in movies | limitTo:2">
<img id="homeThumbnailImg" src="{{imageBaseUrl}}/{{movie.poster_path}}"></img>
{{movie.original_title}}
</div>
</div>
</div>
Home controller
'use strict';
angular.module('home', ['services'])
.controller('homeCtrl', ['$scope', '$q', 'api', 'globals', function($scope, $q, api, globals) {
$scope.imageBaseUrl = globals.getImageBaseUrl();
$scope.getData = function() {
$q.all([
api.discover('movie')
]).then(
function(data) {
$scope.movies = data[0].data.results;
//console.log(data[0].data.results);
},
function(reason) {
console.log(reason);
});
}
$scope.getData();
}]);
API
'use strict';
angular.module('services', [])
.constant('baseUrl', 'http://api.themoviedb.org/3/')
.constant('apiKey', 'myKey...')
.factory('api', function($http, apiKey, baseUrl) {
return {
discover: function(category) {
var url = baseUrl + 'discover/' + category + '?certification_country=US&certification.lte=G&sort_by=popularity.desc&api_key=' + apiKey;
return $http.get(url).success(function(data) {
return data;
});
},
search: function() {
},
...
Thank you all for your time!
You should change your img tag to look like this:
<img id="homeThumbnailImg" ng-src="{{imageBaseUrl}}/{{movie.poster_path}}"></img>
Note the ng-src attribute that replaces the src attribute. This will prevent the browser from trying to fetch the literal string {{imageBaseUrl}}/{{movie.poster_path}} before angular has a chance to eval that expression.
Related
Using angular-ui-router with angular for routing in MEAN application
angular: 1.6.2,
angular-ui-router: 0.4.2
Having following state:
.state('myposts', {
url: '/your-posts',
controller:'PostListController',
templateUrl:'post-list.template.html'
})
.state('postdetail', {
url: '/post/:postId',
controller:'PostDetailController',
templateUrl:'postdetail.template.html',
resolve:{
postdetail: ['Post', '$stateParams', function (Post, $stateParams) {
var url = '/api/posts/edit/' + $stateParams.postId;
return Post.get(url);
}]
}
})
In post-list.template.html listed all posts in table and there is an link to edit particular post by using the following
<a ui-sref="postdetail({ postId: post._id })" class="btn btn-default">
It makes an transition from myposts to postdetail with postId parameter.
Actual URL http://localhost:8886/#/post/58d5167bf05b904a52158f58
Here postId is 58d5167bf05b904a52158f58
Resolve post with postId = 58d5167bf05b904a52158f58 in resolve property of ui-router and inject in PostDetailController controller
function PostDetailController($scope, $state, $stateParams, postdetail, Post){
$scope.post = postdetail;
....
}
It works normally first time, but not working when i refresh the page having url
http://localhost:8886/#/post/58d5167bf05b904a52158f58
Using express server ^4.13.4,
Anyone having solution of above problems, why it is happening
Thanks
I'm trying to invoke a route through and angular service and since I am using $http.post I can't get the route to invoke. I may be going at this all wrong so I'm hoping someone can make a suggestion or point me in the right direction. Initally I have a page load with a controller which once the search command is called it passes a json object with the request to an angular service which then calls webAPI to pass the request onto my other business layers. Here is a logical diagram of the workflow. The response in blue is a new data object being returned to the UI with the users search results.
From my app I have the following routes setup
(function () {
app = angular.module('app', ['ui.bootstrap', 'ngRoute', 'ngAnimate']).value('ngToastr', toastr);
function router($routeProvider) {
$routeProvider.
when('/search/query', {
templateUrl: '../../AngularTemplates/searchResults.html',
controller: 'searchResultCtrl'
}).
otherwise({
templateUrl: '../../AngularTemplates/splashPage.html'
});
}
app.config(['$routeProvider', router]);
//added toaster as factory so it can be injected into any controller
angular.module('app').factory('ngNotifier', function (ngToastr) {
return {
notify: function (msg) {
ngToastr.success(msg);
},
notifyError: function (msg) {
ngToastr.error(msg);
},
notifyInfo: function (msg) {
ngToastr.info(msg);
}
}
});
})();
The initial page calls the controller which has a service dependency
app.controller('searchController', ['$scope', '$filter', 'searchService', 'ngNotifier', '$log', '$timeout', 'searchAttributes' , function ($scope, $filter, searchService, ngNotifier, $log, $timeout, searchAttributes) {
var vm = this;
vm.search = search;
vm.updateEntities = updateEntitySelection;
//bootstraped data from MVC
$scope.userOptions = searchAttributes.mvcData;
//scoped variables
$scope.searchTerm = null;
//ui container for search response
$scope.searchResponse;
$scope.entityList = [
'Search All ',
'Search in Departments ',
'Search in Automotive '
]
$scope.selectedEntity = 'Search All';
function buildSearchRequest() {
var searchResponse = {
searchTerm: $scope.searchTerm,
pageSize: 10,//this will be set by configuration from the UI
pagesReturned: 0,
entityFilter: $scope.selectedEntity
};
return searchResponse;
}
function onError(msg) {
$log.error('An error has occured: ' + msg.data);
}
function updateEntitySelection(entityName) {
$scope.selectedEntity = entityName;
}
function search() {
var request = buildSearchRequest();
searchService.search(request);
}
}]);
and the search service
app.factory('searchService', ['$http', function($http) {
var myEsResults;
function getSearchResults(searchRequest) {
return $http.post('search/query', searchRequest, {}).then(function (response) {
myEsResults = response.data});
}
var getResults = function () {
return myEsResults;
};
return{
search: getSearchResults,
getResults: getResults
};
}]);
What I am trying to accomplish is when the document loads a splash screen is displayed (which works). when the search is executed the request is passed to webapi and then the response is returned as an objectback to the view and a new controller so it can render the search results. I have passed data back and forth between controllers in the past however where I am stuck is using an angular service to call route in webapi. Making this call does not update the page URL and therefore the route is not invoked nor is the second controller loaded to display the results. In the past I have invoked angular routes using a url http://#/route however in this instance I am using an input button with ng-click. I would appreciate any suggestions as to how on the return of data get the 'result view' and controller to load. Is routing the correct approach or is there another way to load the view and controller when using an angular service?
Thanks in advance
<button type="button" class="btn btn-primary btn-lg" ng-click="vm.search()"><span class="glyphicon glyphicon-search"></span></button>
Should be able to do it using $location.path('/search/query')
function getSearchResults(searchRequest) {
return $http.post('search/query', searchRequest, {}).then(function (response) {
myEsResults = response.data;
$location.path('/search/query');
});
}
however workflow seems like it would make more sense to add either routeParams to the url or a search query param and pass url encoded query term to url and make request based on that. Then the request would be made by the searchResultCtrl controller or a resolve in the router config.
Something like:
$routeProvider.
when('/search/query/:queryterm', {
templateUrl: '../../AngularTemplates/searchResults.html',
controller: 'searchResultCtrl'
}).
And path would be generated by:
$location.path('/search/query/' + encodeURIComponent($scope.searchTerm) );
Im simply grabbing my Github information using Github's API. When I log my http request, it displays the right information.. Im not sure why it's not displaying on the page. I'm not getting any errors. (The partial is displaying, just not the requested data)
Service:
myApp.factory('githubApi', ['$http',
function($http) {
//Declaring a promise that will or will not return a users github information.
return {
async: function() {
return $http.get('https://api.github.com/users/joshspears3');
}
}
}
]);
Controller:
myApp.controller('githubCtrl', [ 'githubApi', '$scope',
function(githubApi, $scope){
$scope.data = githubApi.async();
}
]);
Directive:
myApp.directive('githubRequest', [
function() {
return {
scope: {},
restrict: 'E',
controller: 'githubCtrl',
templateUrl: 'public/views/partials/github-request.html'
}
}
]);
github-request.html (partial):
<p class="component-example-header">Creating a service. Grabbing information based on the github API.</p>
<div>
Making a $http request to grab my personal Github information.
<p>Avatar:</p>
<img width="20%"src="{{data.avatar_url}}" alt="" />
<p>Username: {{data.login}}</p>
<p>Followers: {{data.followers}}, Following: {{data.following}}</p>
</div>
Index.html:
<div>
<global-header></global-header>
<div ui-view></div>
<github-request></github-request>
</div>
You haven't used a promise here. Change your async function to:
return $http.get('https://api.github.com/users/joshspears3').success(function(response) {
return response.data
});
and your controller to:
function(githubApi, $scope){
githubApi.async().then(function(data) {
$scope.data = data;
});
}
I'm building my first MEAN twitter like application and currently try to display a list of posts to the gui. what I currently do is:
The angular.js part:
in my main.js:
angular.module('MyApp')
.controller('MainCtrl', ['$scope', 'Feed', function($scope, Feed) {
$scope.feeds = Feed.showFeeds();
// ...
}
in my feed.js:
angular.module('MyApp')
.factory('Feed', ['$http', '$location', '$rootScope', '$cookieStore', '$alert', '$resource',
function ($http, $location, $rootScope, $cookieStore, $alert, $resource) {
return {
// other functions like addFeed: function(f) {...},
showFeeds: function() {
return $http.get('/api/feeds');
}
The node.js part:
app.get('/api/feeds', function (req, res, next) {
var query = Feed.find();
query.limit(8);
query.exec(function (err, feeds) {
if (err) return next(err);
res.send(feeds)
// feeds is a corret JSON with all my data at this point
});
});
and my home.html:
<p>{{ feeds }}</p> <!-- for testing - this just returns {} -->
<div ng-repeat="feed in feeds">
<div>
{{feed.feedMessage}}
</div>
So my problem is: Everything loads fine, but nothing renders out on the page, I don't get any errors, just my $scope.feeds object is empty. I'm pretty new to this, so maybe it's an obvious bug, but if someone could point me in the right direction, that would be great!
Right now you are returning a promise, and you need to be accessing the data.:
Feed.showFeeds().success( function(data) {
$scope.feeds = data.feeds;
});
The '$http' service provided by angular return always an instance of '$q', another angular service which allows us to use the Promise syntax for all async commands.
When you assign the return of Feed.showFeeds() to your scope variable, you bind a promise to your view and Angular can't display it.
You should use the success method provide by $http in order to get the server data and bind them to your scope variable like bencripps said.
Note: The success method (and error) are specific methods of $http and call the $digest method of angular which triggers a refresh of the view automatically.
angular.module('MyApp')
.controller('MainCtrl', ['$scope', 'Feed', function($scope, Feed) {
$scope.feeds = [];
Feed.showFeeds().success(function(data) {
//depends of the json return
//try a console.log(data)
$scope.feeds = data.feeds
});
// ...
}
We are experiencing an issue when running Selenium tests with GhostDriver. We have a Selenium test failure which is influenced by the technologies we've chosen. Our stack is a Lift backend supported by an AngularJS front-end. We are utilizing CometActors to push data to two different AngularJS controllers on the front-end.
When a user visits the site, they will first see the home page which is served by controller one. This controller renders the page with many navigable elements. The second controller is linked to by the links generated (containing $routeParams) on the homepage.
Our test failure appears as we load the page for our Model List page. This page contains the main controller which binds the data we receive from Comet to the template. When the items are visible on the page, we can click them to transition to the second controller. This controller makes a new request to our Lift backend which causes the CometActor to send a response back to the front end. We have verified that everything functions as we expect up to this point including the initial Comet request to retrieve a list of models and the corresponding response meant for the front-end.
The issue appears here... The front-end never executes the JavaScript command supplied in the response from our CometActor. Our CometDispatch.sendModels function is never invoked, preventing an event from triggering an update to the ModelListController. Our Selenium test fails because it cannot find the expected HTML element which should be created when the ModelListController is updated. We are unsure of what happens to the JavaScript command supplied by Comet as it appears it is never executed in the front-end. We verified that our list of Models was not rendering by dumping the page source produced by GhostDriver to the console.
This problem has caused us much confusion as our selenium test passes when driven with Firefox.
CarRegistry.scala
class CarRegistry extends CometActor {
implicit val formats = DefaultFormats
private val adapter: ModelAdapter = new LiftActorModelAdapter
override def lifespan = Full(5 minutes)
def render: RenderOut = {
adapter.handleMessage(ListMakesMessage(this))
"#car-registry-uuid [value]" #> SHtml.jsonCall(Call("function(){}"), fetchModelsByMakeId _).guid
}
def fetchModelsByMakeId(requestJValue: JValue) = {
requestJValue match {
case JInt(makeId) => adapter.handleMessage(ListModelsMessage(this, makeId.toLong))
case _ => ()
}
_Noop
}
override def lowPriority = {
case s # JObject(List(JField(key, JArray(_)))) if key =="make" =>
partialUpdate(Call("CometDispatch.sendMakes", s))
case s # JObject(List(JField(key, JArray(_)))) if key =="model" =>
partialUpdate(Call("CometDispatch.sendModels", s))
case _ => ()
}
}
comet-dispatch.js
var CometDispatch = {
sendMakes: function(makesJson) {
$('body').trigger('makes-received', makesJson);
},
sendModels: function(modelsJson) {
$('body').trigger('models-received', modelsJson);
}
};
app.js
'use strict';
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider, $routeScopeProvider) {
$routeProvider.when('/', {templateUrl: 'static/pages/make-list.html', controller: 'MakeListController'});
$routeProvider.when('/:makeId/list', {templateUrl: 'static/pages/model-list.html', controller: 'ModelListController'});
$routeProvider.otherwise({redirectTo: '/'});
}]);
controllers.js
'use strict';
angular.module('myApp.controllers', []).
controller('MakeListController', function($scope, DataStore) {
$( 'body' ).on( 'makes-received', function( event, makesJsonObj ) {
$scope.$apply(function() {
DataStore.makes = makesJsonObj['makes'];
$scope.makes = makesJsonObj['makes'];
});
});
$scope.makes = $scope.makes || DataStore.makes;
}).
controller('ModelListController', function($scope, $routeParams, CometRequestService) {
$( 'body' ).on( 'models-received', function( event, modelsJsonObj ) {
$scope.$apply(function() {
$scope.models = modelsJsonObj['models'];
});
});
CometRequestService.getModelsFor($routeParams.makeId);
});
services.js
'use strict';
angular.module('myApp.services', []).
factory('DataStore', function() {
return {
makes: []
};
}).
factory('CometRequestService', function() {
return {
getModelsFor: function(makeId) {
liftAjax.lift_ajaxHandler($('#car-registry-uuid').val() + "=" + makeId, null, null, null);
}
}
});
index.html
<div id="main" lift="surround?with=default;at=content">
<h1>Model Directory</h1>
<div lift="comet?type=CarRegistry&randomname=true">
<input type="hidden" id="car-registry-uuid"/>
</div>
<div ng-view></div>
</div>
make-list.html
<div id="make-list">
<div ng-repeat="make in makes">
<a ng-href="#/{{make.id}}/list/" data-dropdown="dd-{{make.id}}">
{{make.name}}
</a>
</div>
</div>
model-list.html
<div id="model-list">
<div ng-repeat="model in models">
<div>
{{model.name}}
</div>
</div>
</div>
This question is also described in this gist.