I am learning angular by building a simple bookstore web app using nodejs as a restful api server. I built the server and it works fine, but once it comes to the front end I face an issue. I built the main page using angular ngRoute to get the data from the server and presented as following:
the picture and the title and the description angular read it with no problem but once I press the button "View Details" I should be redirected to a details page using the book id from the server.
From the front End the route provider:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider.when('/',{
controller: 'BooksController',
templateUrl: 'views/books.html'
})
.when('/books',{
controller: 'BooksController',
templateUrl: 'views/books.hrml'
})
.when('/books/details/:id',{
controller: 'BooksController',
templateUrl: 'views/book_details.html'
})
.when('/books/add', {
controller: 'BooksController',
templateUrl: 'views/add_book.html'
})
.when('/books/edit/:id', {
controller: 'BooksController',
templateUrl: 'views/edit_book.html'
})
.otherwise({
redirectTo: '/'
})
});
Books Controller:
var myApp = angular.module('myApp');
myApp.controller('BooksController', ['$scope', '$http', '$location',
'$routeParams', function($scope, $http, $location, $routeParams){
console.log('BooksController loaded...');
$scope.getBooks = function(){
$http.get('/api/books').then(function(response){
$scope.books = response.data;
});
}
$scope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
}
}]);
books html where the panel being designed:
<div class="panel panel-default" ng-init="getBooks()">
<div class="panel-heading">
<h3 class="panel-title">Latest Books</h3>
</div>
<div class="panel-body">
<div class="row">
<div ng-repeat="book in books">
<div class="col-md-6">
<div class="col-md-6">
<h4>{{book.title}}</h4>
<p>{{book.description}}</p>
<a class="btn btn-primary"
href="#/books/details/{{book._id}}">View Details</a>
</div>
<div class="col-md-6">
<img class="thumbnail" src="{{book.image_url}}">
</div>
</div>
</div>
</div>
</div>
</div>
This the details book html where by clicking the button it must be redirected to:
details_book.html
<div class="panel panel-default" ng-init="getBook()">
<div class="panel-heading">
<h3 class="panel-title">{{book.title}}</h3>
</div>
<div class="panel-body">
<div class "row">
<div class ="col-md-4">
<img src="{{book.image_url}}">
</div>
<div class ="col-md-8">
<p>{{book.description}}</p>
<ul class="list-group">
<li class="list-group-item">Genre: {{book.genre}}</li>
<li class="list-group-item">Author: {{book.author}}</li>
<li class="list-group-item">Publisher: {{book.publisher}}
</li>
</ul>
</div>
</div>
</div>
</div>
and this is the get request from the server to prove the server working find using a certain id
The error I get once I open the main page:
And this error I get once I press the button:
Note: Once I press the button it give me this url:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
where the id is 599701c1f3da51117535b9ab which we can see it in the end of the url. But it should give url exactly such as:
http://localhost:3000/#!/books/details/599701c1f3da51117535b9ab
and once I write this url manually I get to the page which is the details with no problem but once I press the button from the book.html page I get the previews strange url again which is:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
Which load no where.
This is the github url for all the documents:
https://github.com/AbdallahRizk/BookStore.git
Any suggestions Please!!
use $rootScope instead of $scope for getBook function
$rootScope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
init(getBook);
}
Note: add $rootScope to your BookController
Seems like I have hashprefix !, then my URL should also have ! after hash(#)
href="#!/books/details/{{book._id}}"
Since Angular 1.6 hashprefix is defaulted to !, you can disable this behavior by setting hashPrefix to ''(blank).
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('');
}
]);
Note: This answer from, #Pankaj Parkar at I get a weird templateURL not as it suppose to give with angular?
Related
I am able to get only 10 objects while accessing an api and nothing through custom directive.Can anyone suggest something?
Below is the code. Can anyone help? The specialCard directive is not accessing data below.
mainView.html
<div class="panel panel-primary col-sm-offset-2 col-xs-12 col-sm-8">
<special-card></special-card>
</div>
</div>
postcard.html
<div class="post-preview" ng-repeat="book in BooksData">
<div class="panel panel-primary col-sm-offset-2 col-xs-12 col-sm-8">
<div class="panel-heading"> <h4>Book - {{book.name}}</h4></div>
<div class="panel-body">
<div>Author - <em>{{ book.authors[0] }}</em> </div>
<div>Publisher - <em>{{ book.publisher}}</em> </div>
<div>ISBN - <em>{{ book.isbn}}</em> </div>
<br>
<a class="btn btn-primary" ng-href="#/{{type}}/{{book.isbn}}"> Details</a>
</div>
</div>
</div>
</div>
app.js
var myApp = angular.module('blogApp', ['ngRoute']);
myApp.directive("specialCard",function(){
return{
restrict : "E",
templateURL : "views/post-card.html",
controller : function($scope){
}
}
});
myApp.controller('mainController',['$http','$scope',function($http,$scope) {
$http.get('https://anapioficeandfire.com/api/books').success(function(data){
$scope.BooksData= data;
console.log($scope.BooksData);
});
}]);
myApp.controller('characController',['$http','$scope',function($http,$scope) {
$http.get('https://www.anapioficeandfire.com/api/characters?page=1&pageSize=20').success(function(data1){
$scope.charData= data1;
console.log($scope.charData);
});
}]);
myApp.controller('houseController',['$http','$scope',function($http,$scope) {
$http.get('https://anapioficeandfire.com/api/houses?page=1&pageSize=20').success(function(data2){
$scope.houseData= data2;
console.log($scope.houseData);
});
}]);
Routes
myApp.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/',{
// Which controller it should use
controller : 'mainController',
// what is the alias of that controller.
controllerAs : 'main'
})
.when('/books',{
templateUrl : 'views/mainView.html',
controller : 'mainController',
controllerAs : 'main'
})
otherwise(
{
//redirectTo:'/'
template : '<h1>404 page not found</h1>'
}
);
}]);
It's impossible to help you with a such question.
Firstly, please follow the recommandations of this article: How do I ask a good question?
Then don't paste any links to GitHub repo, provide code directly in the question (and properly formatted) with some examples if you can (demo on Plunkr, Jsfiddle, etc.)
i am new in angularjs i have a index page with some data with anchor tag when user click in a particular anchor tag page redirect to list page and show data but ngRoute not working and also the not getting the query string value. Where i wrong
this is my index page
<div class="all_cat" ng-repeat="state in statelist">
<h2>{{state.Statename}}</h2>
<div class="cat-col-4" ng-repeat="citylist in state.city">
<ul>
<li><i class="fa fa-caret-right"></i>{{citylist.cityname}} ({{citylist.jobcount}})</li>
</ul>
</div>
<div class="clear"></div>
</div>
and this is my js
var app = angular.module('angularTable', ['ngSanitize', 'ui.select', 'angularTrix', 'ngRoute']);
app.config(function($routeProvider) {
debugger;
$routeProvider
.when('/JobList:ID', {
templateUrl: 'job/JobList.cshtml',
controller: 'joblist'
})
});
app.controller('joblist', function($scope, $routeParams) {
debugger;
$scope.message = 'Clicked person name from home page should be display here';
$scope.person = $routeParams.ID;
});
i am not under stand where i do wrong
Ass braja lal Mahanty tell you might want /JobList/:ID instead of /JobList:ID.
So you have to set state as:
$routeProvider
.when('/JobList/:ID', {
templateUrl: 'job/JobList.cshtml',
controller: 'joblist'
})
});
I have a listing of blog posts and I want to be able to click on the title and have it dynamically redirect to the proper posting.
So far it works except when I click on the anchor tagged title it redirects to:
blog/#/post/:post
rather than
blog#/post/:post
I've tried to change the href to data-ng-href,
using target="_self"
and tried changing the href="#/post/{{post}}" and href="/post/{{post}}"
Routes:
(function(){
'use strict';
angular.module('ghpg')
.config(Config);
Config.$inject = ['$routeProvider'];
function Config($routeProvider){
$routeProvider
.when('/listing', {
templateUrl: '/angular/views/listing.client.view.html'
}).otherwise({
redirectTo:'/'
}).when('/post/:title',{
templateUrl: '/angular/views/post.client.view.html',
controller: 'postController',
controllerAs: 'post'
}).otherwise({
redirectTo:'/listing'
});
}
})();
Listing View:
(function(){
'use strict';
angular
.module('ghpg')
.controller('listingController', listingController);
listingController.$inject = ['$scope', 'blogContent'];//,'blogContent'] //, 'blogContent'];
////
function listingController($scope, blogContent){
var vm = this;
vm.articles = [];
grabData();
function grabData(){
return blogContent.getContent().then(function(data){
console.log(data.articles);
vm.articles = data.articles;
return vm.articles;
},function(err){
console.log(err);
vm.data = [];
});
}
}
})();
App.js:
(function(){
'use strict';
var dependencies = [
'ghpg',
'ngRoute'
];
angular.module('blogger', dependencies)
.config(Config);
Config.$inject = ['$locationProvider']
function Config($locationProvider){
$locationProvider.hashPrefix('!');
}
if (window.location.hash === '#_=_'){
window.location.hash = '#!';
}
//bootstrap angular
angular.element(document).ready(function(){
angular.bootstrap(document, ['ghpg']);
});
})();
LISTING VIEW:
<div class="container-fluid" data-ng-Controller="listingController as vm">
<h2> Listings </h2>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="post-listing" data-ng-repeat="post in vm.articles">
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
<div class="article-container">
<div class="article-date"><span class="article-date">{{ post.date }}</span></div>
<div class="article-post>"><span class="article-content"> {{ post.content }} </span></div>
</div>
</div>
</div>
</div>
</div>
Having trouble where I went wrong. I strongly suspect that it's some small typo or something with my SPA location/locationProvider in app.js but it looks the same in my other apps, unless my eyes are fooling me (which could be totally happening!)
What I did for a fix was simply this:
changed the listing view's anchor:
<h3 class="article-title"><a target="_self" data-ng-href="/post/{{post.title}}"> {{ post.title }} </a></h3>
to include the /blog# portion in the href so that I have:
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
Simple fix, cause only the blog portion or webpage of my website is the angularJS, everything else is not so the routing was not being called to route it until it saw /blog# as part of the app.
I have an angular web app that I am trying to get escaped_fragments to work using Mean-seo (under the covers it uses phantomjs headless browser)
I am getting strange behaviour I can't explain.
The non escaped fragment works fine.
With escaped fragments some of the content immediately disappears.
I have an object that I am reading from the mongo db in the resolve section of the routes config like so.
state('view-creator-test', {
url: '/view-creator-test/:creatorId',
templateUrl: 'modules/creators/views/view-creator-test.client.view.html',
resolve: {
creator: function($stateParams, Creators) {
return Creators.get({
creatorId: $stateParams.creatorId
}).$promise;
}
},
controller: function($scope, creator) {
$scope.resolveCreator = creator;
}
}).
then the view template is
<section data-ng-controller="CreatorTestController" >
<!-- !CREATOR PROFILE -->
<section class="profile-header inverse">
<div class="container">
<!-- AVATAR -->
<div class="row">
<!-- NAME / LOCATION -->
<div class="col-sm-8 col-sm-offset-1 col-xs-12 text-center-sm">
<div class="row">
<div class="col-sm-6 col-xs-12">
<h2 class="name">{{creator.name}}</h2>
<h2 class="name" ng-bind="creator.name"></h2>
</div>
<h2 class="name">{{test}}</h2>
<h2 class="name" ng-bind="test"></h2>
</div>
</div>
</div>
</div>
</section>
</section>
then the controller is
'use strict';
angular.module('creators').controller('CreatorTestController', ['$scope',
function($scope) {
$scope.test = 'Leo was Here';
$scope.creator = $scope.resolveCreator;
}]);
the result is that the creator name is filled in for {{creator.name}} but is not filled in for ng-bind="creator.name".
'Leo was here' is filled in for both.
Thanks
Instead of defining controller function in state and then do assign that $scope inside variable through template, you could place the CreatorTestController inside the route, so that you directly inject the dependency inside the CreatorTestController function, Remove ng-controller from the template
.state('view-creator-test', {
url: '/view-creator-test/:creatorId',
templateUrl: 'modules/creators/views/view-creator-test.client.view.html',
resolve: {
creator: function($stateParams, Creators) {
return Creators.get({
creatorId: $stateParams.creatorId
}).$promise;
}
},
controller: 'CreatorTestController'
})
Controller
'use strict';
angular.module('creators').controller('CreatorTestController', ['$scope', 'creator', //<-- injected resolve method here.
function($scope, creator) {
$scope.test = 'Leo was Here';
$scope.creator = creator;
}]);
Within my view I am outputting links. When I go to click a link it triggers the otherwise method in my routeProvider and ends up redirecting back to home. I need it to redirect indiv id and I need to be able to grab project.id from my view within my controller. May I please have some assistance. I'm kind of stuck.
My view:
<div class="container clearfix">
<div class="pagename sixteen columns fadeInUp animated">
<h1 style="font-family: Merriweather">Portfolio</h1>
</div>
</div>
<div class="container clearfix" ng-controller="portfolioController">
<ul style="padding-left: 20pt" class="large-block-grid-4 align-center">
<li class="part" ng-repeat="project in projects">
<a href="#/indiv?id={{ project.id }}">
<img src="{{ project.screenshot_uri }}" alt="">
</a>
<br><br>
<h4>{{ project.project_name }}</h4>
<p>{{ project.description }}</p>
</li>
</ul>
</div><br><br>
My app data:
var app = angular.module("app", ['ngRoute']).config(function($httpProvider, $routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'index.php/projects/projects/home',
controller: 'homeController'
});
$routeProvider.when('/portfolio', {
templateUrl: 'index.php/projects/projects/portfolio',
controller: 'portfolioController'
});
$routeProvider.when('/indiv:id', {
templateUrl: 'index.php/projects/projects/indiv',
controller: 'indiv_controller'
});
$routeProvider.when('/contact', {
templateUrl: 'index.php/projects/projects/contact',
controller: 'contactController'
});
$routeProvider.otherwise({ redirectTo: '/home' });
});
app.factory('pull_projects', function($http) {
return {
get_projects: function(callback) {
$http.get('index.php/projects/pull_projects').success(callback);
}
};
});
app.controller('portfolioController', function($http, $location, $scope, pull_projects) {
pull_projects.get_projects(function(results) {
$scope.projects = results;
});
});
app.controller('contactController', function($http, $location, $scope) {
});
app.controller('indiv_controller', function($http, $location, $scope, $routeParams) {
alert($routeParams.id);
});
app.controller('homeController', function($http, $location, $scope) {
});
Seems the problem is that you are defining the angular routing url and the url in the markup slightly different.
Route:
In the route url you are defining /indiv:id. However, this would match a url where the id was part of the indiv part. So, http://host/indiv123.
So, I would suggest changing this to: /indiv/:id. This will then match urls like this: http://host/indiv/123.
Markup:
In the HTML you are declaring the url as #/indiv?id={{ project.id }}. This will produce the url: /indiv?id=123.
To match our new angular route we need the template to be #/indiv/{{ project.id }} so that we produce a url like /indiv/123.
Hope this helps.
You should use :
ng-href="#/indiv?id={{ project.id }}"
instead of
href="#/indiv?id={{ project.id }}"
This ensures that {{ project.id }} is correctly resolved before it is used as a link.
This occurs because Angular not always gets the chance to intercept the data binding requests before the browser attempts to resolve href and src (<img src="">) attributes. Accordingly, you should use ng-src for images.