first of all sorry if I write with bad grammar/expressions, my english is not the best.
Well, I'm trying to show a product via ID, for this I'm sending this ID from a list of products with this url: localhost/products/product/:ID and I'm receiving GET http://localhost/products/product/101 404 (Not Found)(the 101 is an example).
If I go to http://localhost/products/product.html it is changed for http://localhost but is not redirected, just change the url in the address bar
Here is my code
var app = angular.module('AppMarketApp', ['ngRoute']);
app.config(function($routeProvider, $locationProvider){
$locationProvider.html5Mode({
enabled:true,
requireBase: false});
$routeProvider
.when("/products/product/:codProd", {
templateUrl: '../js/product/appInfo.html',
controller: 'Controller'
})
.otherwise({redirectTo:'/'});;
});
app.controller("Controller",['$scope','$http', '$routeParams', function($scope,$http, $routeParams){
$scope.row = {};
var codProd= $routeParams.codProd;
//some extra code here.
directive
app.directive('appInfo', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: '../js/product/appInfo.html'
};
});
and html
<body ng-app="AppMarketApp" ng-controller="Controller">
<div class="page" style="">
<div class="content-showproduct">
<div class="product" ng-view>
<app-info info="arts"></app-info>
</div>
</div>
</div>
<script src="../js/product/Controller.js"></script>
<script src="../js/product/appInfo.js"></script>
</body>
Any ideas? if you guys need some extra info let me know.
In addition, I think that I have some bad code in the HTML file, more specifically here
<div class="product" ng-view>
<app-info info="arts"></app-info>
</div>
I dont know if it will work well after routing. Without ng-view in others files works well. But is not important right now.
Related
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?
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 get a dom like this:
<div class="row">
<::before>
<div class="col-lg-12">
<!-- ngView: undefined -->
<ng-view class="ng-scope">
<h1 class="ng-scope">Hello world</h1>
</ng-view>
</div>
<::after>
</div>
What does:
<!-- ngView: undefined -->
mean?
Everything seems to work fine, but I don't like this comment as it seems that something is not working properly?
The template look like this:
<h1>Hello world</h1>
and it is configured like this :
var myApp = angular.module('myApp', [
'ngRoute',
.....
]);
myApp.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/my_template', {templateUrl: '/web-angular/my_template.html'})
.when( ..... );
}]);
Place your 'ng-view' directive in a div or span. Such as ...
<div ng-view></div>
<span ng-view></span>
Check out the IE restrictions here AngularJS IE Guide and take a look at number 3 and 4. From this, I take it that this is simply a warning. Something to catch your attention, and mine, just as it did. Note that declaring ng-view in your class will still work, but you will get the same warning message in your markup.
For anyone else coming across this and not having any luck with the other answer, I had this problem because I hadn't included the controller as a dependency of the module.
angular.module('myApp', ['module-for-missing-page'])
Including this dependency got the view loading correctly.
inject ur view in an anchor tag.Like this
<div>
Home
Students
Courses
<ng-view> </ng-view>
</div>
var app = angular.module("MyApp", ["ngRoute"])
.config(function ($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "Templates/home.html",
controller: "homeController"
})
.when("/courses", {
templateUrl: "Templates/courses.html",
controller: "courseController"
})
.when("/students", {
templateUrl: "Templates/students.html",
controller: "studentsController"
})
})
.controller("homeController", function ($scope) {
$scope.message = "I am in home controller";
})
.controller("courseController",function($scope){
$scope.message = "I am in courses controller";
})
.controller("studentsController", function ($scope) {
$scope.message = "I am in students controller";
})
and check whether u have put the correct ng-route links or not.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"> </script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.min.js">
</script>
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.
I have an app that behaves normally when I follow links on the page, but if I use the browser's back and forward buttons, it breaks in the following ways:
It sends a request to the server, but only on "Back".
The template is not rendered at all.
In addition, when I hit "back" to go from page B to page A, chrome's "refresh/stop" button flickers between the top options rapidly, and repeated attemptes to go back and forward causes longer flickering.
Here are the code snippets that I think are relevant:
Edit: I'm working on a plnkr but the site is currently not working. I'll update when it's up and I can verify the bad behavior
Edit 2: Here is the plnkr, but it has problems. It can't find the templateUrls specified in app.js routing, not sure why. Here's the code anyway http://plnkr.co/edit/6cQtnvLi10sJKW8jVzVM
Edit 3: With the help of a friend, I think the problem is coming from using turbo-links on rails 4. I can't test it right now, but when I can I'll post an answer if it works.
file: app.js
window.App = angular.module('app', [
'templates',
'ui.bootstrap'
])
.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
controller: 'HomeCtrl',
templateUrl: 'home.html'
})
.when('/bars', {
controller: 'BarsPublicCtrl',
templateUrl: 'bars_public.html'
})
.when('/bars/:bar_name', {
controller: 'BarsDetailPublicCtrl',
templateUrl: 'bars_detail_public.html'
})
.otherwise({redirectTo: '/'});
}]);
file: bars_public_ctrl.js
App.controller('BarsPublicCtrl', ['$scope', '$location', 'BarsPublicDataFactory',
function($scope, $location, BarsPublicDataFactory) {
// memoization
$scope.bars = $scope.bars || BarsPublicDataFactory.getBars();
}
]);
BarsPublicDataFactory just returns a static array of fake data, same with the factory in the following snippet
file: bars_detail_public_ctrl.js
App.controller('BarsDetailPublicCtrl', ['$scope', '$routeParams', 'BarsDetailPublicDataFactory',
function($scope, $routeParams, BarsDetailPublicDataFactory) {
$scope.bar = {};
$scope.bar.name = $routeParams.barId;
$scope.barDetails = BarsDetailPublicDataFactory.getBaz($routeParams.bar_name);
$scope.Bazs = BarsDetailPublicDataFactory.getBazs();
}]);
file: bars_public.html
<div class="container">
<div ng-repeat="bar in bars">
<div class="row">
<div class="col-sm-12">
<a href="/bars/{{bar.name}}">
<h4 style="display:inline;">{{ bar.name }}</h4>
</a>
</div>
</div>
<hr />
</div>
</div>
file: bars_detail_public.html
<select ng-model="searchSelect.style" style="width:100%;">
<option value='' selected>All</option>
<option ng-repeat="baz in bazs">{{baz}}</option>
</select>
<div>
<accordion close-others="true">
<accordion-group ng-repeat="foo in foos | filter:searchSelect">
<accordion-heading>
<div>
<h3>{{foo.name}}</h3>
<em>{{foo.style}}</em>
</div>
</accordion-heading>
</accordion-group>
</accordion>
</div>
If you need anything else, let me know.
It turns out that the problem was caused by turbolinks with Rails 4. I failed to mention it because I didn't realize it was important.
I don't know exactly what caused it, but turbolinks injects some javascript, and as best as I can tell, it highjacks some events that cause the page to reload when you use the browse buttons which was breaking my app.
So I followed this advice: http://blog.steveklabnik.com/posts/2013-06-25-removing-turbolinks-from-rails-4
and it worked just fine! Hope someone else can benefit.
befoure:
[installed]jquery_turbo_links
[installed]turbolinks
alter:
[installed]jquery_turbo_links
[removed]turbolinks
It worked!