MVC and AngularJS routing - angularjs

I have created an MVC application and added an Angularjs nuget.
It was created HomeController and view for it.
Home controlled isn't changed at all.
My folder hierarchy:
Index.cshtml:
<!DOCTYPE html>
<html>
<head>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/App/App.js"></script>
<title>Title</title>
</head>
<body ng-app="sampleApp">
Route 1<br />
Route 2<br />
<div ng-view></div>
<script>
var module = angular.module("sampleApp", ['ngRoute']);
module.config(
function ($routeProvider, $locationProvider) {
$routeProvider.
when('/route1', {
templateUrl: 'Views/Home.html',
controller: 'RouteController'
}).
when('/route2', {
templateUrl: 'Views/Home.html',
controller: 'RouteController'
}).
otherwise({
redirectTo: '/'
});
});
module.controller("RouteController", function ($scope) {
alert("I am here");
})
</script>
</body>
</html>
Clicking on the links produces an 404 error
http://localhost:50265/Home/Views/Home.html - this is link that was generated.
I don't understand why there is Home inserted in link.
And as the page of error said that it expected physical path
E:\SoftServe\IndividualTask\IndividualTask\Home\Views\Home.html
but i don't have Home folder in root folder E:\SoftServe\IndividualTask\IndividualTask
I set the route to 'Views/Home.html' but not to 'Home/Views/Home.html'.
What is the base path for routing? How to make it work?

MVC doesn't allow to access files from view folder..you need to
manipulate that thing by defining handler in web.config
Thank you. I have found this article: http://forums.asp.net/t/1689087.aspx?ASP+NET+MVC+Using+content+in+Views+folder and replace
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
on
<add name="BlockViewHandler" path="*.cshtml" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
in web.config file that allows to get files from the View folder and doesn't allow only *.cshtml files from it.

Related

Angular routing doesn't work

Disclaimer: Yes, I have read many other posts, but haven't been able to find the solution.
So, I have set up a basic Angular app:
index.html
<!DOCTYPE html>
<html ng-app="sampleApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div class="navbar">
Home
About me
Projects
Contact
</div>
<div ng-view></div>
</body>
</html>
app.js
var myApp = angular.module('sampleApp', ['ngRoute']);
myApp.config(
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/main.html'
}).
when('/aboutme', {
templateUrl: 'views/aboutme.html'
}).
when('/projects', {
templateUrl: 'views/projects.html'
}).
when('/contact', {
templateUrl: 'views/contact.html'
}).
otherwise({
redirectTo: '/'
});
}
);
When I start the server (npm install http-server followed by http-server -o) and run the app, I can see the main.html content and the navigation links. The URL is http://127.0.0.1:8080/#!/. When I click e.g. Projects, the URL becomes http://127.0.0.1:8080/#!/#%2Fprojects, but the page content is still the same (navigation links + main.html's content).
I have also tried modifying app.js like this:
...
myApp.config(['$routeProvider',
function($routeProvider) {
...
}]);
...but the outcome is the same.
What am I doing wrong?
it seems to be working fine. And as mention in the comments need to check the angular version. i create a sample Plunker
<script data-require="angular.js#1.5.10" data-semver="1.5.10" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>
<script data-require="angular-router#1.2.0-rc1" data-semver="1.2.0-rc1" src="https://code.angularjs.org/1.2.0rc1/angular-route.js"></script>

AngularJS routing with templateUrl

I have a problem with the AngularJS routing: I don't get any feedback of the page. No errors or view-switches.
I checked my implementation of the module, but it's declared in the right way. Then I searched for typos such as templateURL, but I didn't find any. I also tried to use ng-href instead of href in the list, but then the links weren't clickable anymore.
Here is my plunker.
And my code:
Created my navigation:
<body ng-app="Productportfolio">
<ul>
<li>
Home
</li>
<li>
<a href='#/privat'>Log in</a>
</li>
</ul>
<ng-view></ng-view>
<!--own js -->
<script src="app.js"></script>
<!--Controller -->
<script src="ProductCtrl.js"></script>
<!--Services -->
<!--Direktives-->
</body>
Made the templates:
//home.html
<div>
<h1> Home </h1>
</div>
//private.html
<div>
<h1> Private</h1>
</div>
Declared a Angular module:
angular.module('Productportfolio', ['ngRoute'])
Added the $routeProvider to my config:
angular.module('Productportfolio', ['ngRoute', 'ProductService', 'ProductCtrl'])
.config(['$routeProvider, $locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'ProductCtrl'
})
.when('/private', {
templateUrl: 'private.html',
controller: 'ProductCtrl'
})
.otherwise({
redirectTo: '/home',
controller: 'ProductCtrl'
});
$locationProvider.hashPrefix('!');
}]);
In your Plunker, there were some issues related to imports. To make it easy, I simply removed both jQuery and Bootstrap. I also put all your modules in a single app.js file.
There were some errors in your html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<!--AngularJS-->
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script data-require="angular-route#1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular-route.js"></script>
</head>
<body ng-app="Productportfolio">
<ul>
<li>
<a ng-href="#home">Home</a>
</li>
<li>
<a ng-href="#private">Private</a>
</li>
</ul>
<ng-view></ng-view>
<!--own js -->
<script src="app.js"></script>
</body>
</html>
Import Angular BEFORE ngRoute or any other module
Use ng-href='#routeName' or, otherwise
And in your js:
var myApp = angular.module('Productportfolio', ['ngRoute']);
myApp.controller('ProductCtrl', ['$scope',function ($scope) {
var vm = this;
}]);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'ProductCtrl'
})
.when('/private', {
templateUrl: 'private.html',
controller: 'ProductCtrl'
})
.otherwise({
redirectTo: '/home',
controller: 'ProductCtrl'
});
}]);
You need to inject only external modules in your app module, not all controller, services etc
Notice that, to make it easy, I removed also your Service since you did not share it and it was useful.
Last but not least, if you want to use $locationProvider.hashPrefix('!'); to use hashbangs, you need to add <base href="/" /> at the end of your head.
For some reason, plunker does not allow me to do that, but I'm sure you'll get it to work on your version.
Here You can find the working plunker reproducing your application.
Hope I've been helpful.
The remaining and not visible problem is here :
angular.module('Productportfolio', ['ngRoute', 'ProductService', 'ProductCtrl'])
.config(['$routeProvider, $locationProvider',
config() function of module object takes as parameter, a array of strings and not a string with "," as separator char inside it.
See example and doc here :
https://docs.angularjs.org/guide/providers#provider-recipe
So, it should be :
angular.module('Productportfolio', ['ngRoute', 'ProductService', 'ProductCtrl'])
.config(['$routeProvider', '$locationProvider',
Update :
But in fact, in your case, it works even without precising the array :
angular.module('Productportfolio', ['ngRoute', 'ProductService', 'ProductCtrl'])
.config(
I updated the plunker and the app.js with both versions. I have the impression that the array is not mandatory (any longer). So, it seems better to ignore that parameter, especially, if with bad value, it may create side-effects.
Here the plunker with corrections (ordered lib, typos and config function called) :
http://plnkr.co/edit/NTn6Zmav5RX4V8zgHPOG?p=preview
I have removed $locationProvider.hashPrefix('!') as not suitable for the url you are using. See #AndreaM16 answer for that.
Besides, you have not declared your service you want to use in your controller.
app.js
angular.module('Productportfolio', ['ngRoute'])
.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'ProductCtrl'
})
.when('/private', {
templateUrl: 'private.html',
controller: 'ProductCtrl'
})
.otherwise({
redirectTo: '/home',
controller: 'ProductCtrl'
});
}]
);
or app.js without the array parameter in config function :
angular.module('Productportfolio', ['ngRoute'])
.config(
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'ProductCtrl'
})
.when('/private', {
templateUrl: 'private.html',
controller: 'ProductCtrl'
})
.otherwise({
redirectTo: '/home',
controller: 'ProductCtrl'
});
// $locationProvider.hashPrefix('!');
}
);
index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<!--Bootstrap-->
<script data-require="jquery#*" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script><!-- Tether for Bootstrap -->
<link data-require="bootstrap#*" data-semver="4.0.0-alpha.2" rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" />
<script data-require="bootstrap#*" data-semver="4.0.0-alpha.2" src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<!--AngularJS-->
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script data-require="angular-route#*" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular-route.js"></script>
<!--own js -->
<script src="app.js"></script>
<!--Controller -->
<script src="ProductCtrl.js"></script>
<!--Services -->
<!--Direktives-->
</head>
<body ng-app="Productportfolio">
<ul>
<li>
Home
</li>
<li>
Log in
</li>
</ul>
<div ng-view></div>
</body>
</html>
The order of loading java script files is very important. Load in the following order:
<link data-require="bootstrap#*" data-semver="4.0.0-alpha.2" rel="stylesheet"
href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" />
<script data-require="jquery#*" data-semver="3.0.0"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://www.atlasestateagents.co.uk/javascript/tether.min.js"></script>
<script data-require="bootstrap#*" data-semver="4.0.0-alpha.2"
src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<!--AngularJS-->
<script data-require="angularjs#1.5.8" data-semver="1.5.8"
src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script data-require="angular-route#*" data-semver="1.5.8"
src="https://code.angularjs.org/1.5.8/angular-route.js"></script>
It means that you are loading Bootstrap.js files, but Bootstrap cannot work without jQuery library. So it means you should load jQuery at first, then Bootstrap.js. And other libraries should be reordered(I've shown in an example above).
In addition, you can use Console in your browser to see whether there are errors and what errors you have.

Cannot manually navigate to urls

Whenever I manually enter a url into my browser to a site built with Angular, I get:
'HTTP 404
The resource cannot be found
Requested URL: /register'
The only navigable url is http://localhost:XXXX/index.html, from there I have to navigate around the site with anchor tags.
My config file for Angular looks like this:
app.config(function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
//.hashPrefix('!')
$routeProvider
.when('/', {
templateUrl: '/Client/AngularViews/home.html'
})
.when('/register', {
templateUrl: '/Client/AngularViews/register.html',
controller: 'registerController'
})
.when('/post-register', {
templateUrl: '/Client/AngularViews/postRegister.html',
controller: 'registerController'
})
.otherwise({ templateUrl: 'Client/AngularViews/home.html' });
});
Index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="app">
<head>
<script type="text/javascript" src="Scripts/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="Scripts/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript" src="Scripts/mainController.js"></script>
<base href="/" />
</head>
<body>
<div class="container-fluid">
<div ng-view></div>
</div>
Can someone explain to me what I'm doing wrong? I want to be able to manually enter urls into the address bar and navigate to anything other than index.html
According to documentation:
Server side
Using this mode requires URL rewriting on server side,
basically you have to rewrite all your links to entry point of your
application (e.g. index.html). Requiring a tag is also
important for this case, as it allows Angular to differentiate between
the part of the url that is the application base and the path that
should be handeled by the application.
https://docs.angularjs.org/guide/$location
So you need some additional support from server-side: configure your http server to reply with index.html for all url you have in your apps.
I use ASP.Net MVC for server side URL rewriting using controllers. Probably not its intended use but works well

Routing with AngularJS and MVC

I have been searching the web for solutions but cant't find any that will solve my problem.
I am trying to do client side routing with AngularJS and MVC.
This is the Plunker that I am using for guide lines but it does not help me. My MVS2 Project folder structure is as follows:
$root/Views/Home/Home.html
The error I get that the page could not be found. What am I missing here?
AngularJS
// create the module and name it myApp
var myApp= angular.module('myApp', ['ngRoute']);
// configure our routes
myApp.config(function ($routeProvider) {
$routeProvider.when('/', {templateUrl: 'Home.html',controller: 'mainController'})
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function ($scope) {
// create a message to display in our view
$scope.message = 'Home Page should appear here';
});
HTML
<html data-ng-app="myApp">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</title>
</head
<body data-ng-controller="mainController">
<div id="Div1">
<div data-ng-view></div>
</div>
</body>
</html>
MVC blocks the Views folder from being accessed! It will always return HTTP status 404!
Why? This is done for security. It prevents visitor from looking at your view files (ascx, cshtml, vbhtml, etc) which is source code.
How it's done? You will notice that Viewsfolder has a web.config. Web.config is configured to return 404.
Here is a snippet of the web.config
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
Notice that for any path and any HTTP method, the handler is HttpNotFoundHandler
Solution: don't use the View folder for your AngularJS templates or modify web.config at your own risk
The answer that LostInComputers gave me I have found a solution to inject html pages to my MVC project.
.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/templates/Home.html',
controller: 'mainController'
})
.when('/about', {
templateUrl: '/templates/About.html',
controller: 'mainController'
})
$routeProvider.otherwise({ redirectTo: '/' });
});
What I did was to create a template folder in my root directory and added my .html pages in there.
This works perfectly for me.

ng-views only work through web server?

I have a simple test app that uses ng-view. It works perfectly whey I access
it through a web server. However, when I try to open the main page
from my local drive the views appear to stop working. I suspect that the path to
the views cannot be found and therefore cannot display, however when using $location to
confirm the path, it seems to be correct.
Other data bindings are working on the page, so Angular seems to be loading and running
correctly.
JAVASCRIPT:
var app = angular.module("MyApp", []);
app.config(function ($routeProvider) {
$routeProvider
.when("/item/:Id",
{
templateUrl: "partials/itemdetail.html",
controller: "itemController"
})
.when("/items",
{
templateUrl: "partials/items.html",
controller: "itemsController"
})
.when("/",
{
templateUrl: "partials/items.html",
controller: "itemsController"
})
.otherwise({ redirectTo: '/' });
});
HTML:
<html data-ng-app="MyApp">
<head>
<title></title>
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript" src="js/application.js"></script>
</head>
<body data-ng-controller="itemsController">
<img src="{{Logo}}" width="300" />
</br>
<div data-ng-view></div>
</body>
</html>
Opening a file directly in your browser causes it to have no domain. As a result, trying to retrieve files via AJAX (such as your templates) results in a domain security exception. Trying running a local server in your directory.
If you're on a mac, open terminal, navigate to your directory and type:
python -m SimpleHTTPServer

Resources