I am new to Angular and I need help with UI Router. I need to load mylink.html after clicking on link. Here is my code:
var app = angular.module('hollywood', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false});
$stateProvider.state('mylink', {
templateUrl: 'mylink.html'
});
})
<a ui-sref="mylink">My Link</a>
<article ui-view></article>
What am I doing wrong? There is no error in console, except error after click:
XMLHttpRequest cannot load .... Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
The thing is file is local and I don't think I can set up CORS in these case.
https://jsfiddle.net/2q61mcp9/
Try using this code
var app = angular.module('hollywood', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$stateProvider.state('mylink', {
url: '/my-link',
templateUrl: 'mylink.html' // give absolute url like src/views/mylink/html
});
})
You missed to add url in state object
#Damian Are you serving your angular app via some kind of server (python ,node etc), or are you simply running the app via file system(Directly via open with browser option) in browser ?
If you are directly running it you are most likely to get this CORS issue as browsers dont allow resource sharing via file system for security issues.
My code is correct. I've deleted 'url' and run it on server. It work's.
Related
I'm using adal-angular js library-adal-angular for authentication which generates token. When login is made and it redirects, the token is appended to querystring like this https://localhost:8800/Index.html#id_token=eyJ0eXAiOiJKV1QiLCJhb...
Why this is happening, what should I do to avoid token on URL?
I've checked this and tried the solution but it's not working for me. Anything I'm doing is wrong? Can anyone please help me?
Here is the code I'm using,
app.js
var app = angular.module('app', [
'ngRoute',
'AdalAngular',
]);
app.config([
"$routeProvider",
"$locationProvider",
"adalAuthenticationServiceProvider"
function (
$routeProvider,
$locationProvider,
adalProvider
) {
$locationProvider.hashPrefix("");
adalProvider.init(configuration_object, $httpProvider);
$routeProvider
.when("/abcd", {
templateUrl: urlBase + "abcd.html" + version,
controller: "abcdCtrl",
requireADLogin: true,
})
.otherwise({
redirectTo: "/login",
});
}
loginCtrl.js
angular.module("app").controller("loginCtrl", [
"adalAuthenticationService",
function (
adalService
) {
adalService.login();
}
}
The token is returned in the query string because adal-angular uses the Implicit Grant, where the tokens are returned from the authorization endpoint directly instead of the app acquiring them from the token endpoint.
To hide them from the URLs, you will need to use the Authorization Code Grant with PKCE.
This flow is supported only by the newer versions of MSAL.js, there is an Angular wrapper here: https://www.npmjs.com/package/#azure/msal-angular.
You will also need to change your reply URLs to Single Page Application platform so that this newer flow is supported.
If you want to know how this flow works, the documentation has some details: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow.
Essentially, only an authorization code is passed in the URL, the tokens are acquired from the token endpoint with an HTTP request from your front-end.
Do note in both of these flows the tokens are still visible to the users of your app, since the code runs on their machines :)
So I needed to change my URL so that google analytics could track it. Google analytics wouldn't accept it with the "/#/" (hash) in the link. That said, I used Angular's locationProvider and revised my app routing with:
(function() {
'use strict';
angular
.module('mbapp')
.config(routerConfig);
/** #ngInject */
function routerConfig($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
});
$stateProvider
.state('steps', {
url: '/steps',
templateUrl: 'app/steps/steps.html',
controller: 'StepsController',
controllerAs: 'steps'
});
// use the HTML5 History API
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
}
})();
My URL is fine and changes it to http://website.com/steps rather than http://website.com/#/steps. However, now, if a user refreshes (f5) the link it then throw a 404 error and not sure why. Additionally, it seems that somehow this gets injected as the URL when the refresh is called "http://website/steps#/steps".
Any ideas on this?
Thanks much.
The problem is probably on the server side. You have to configure your server so it responds to every request with your html file. For example in express:
var app = require('express')();
app.configure(function(){
// static - all our js, css, images, etc go into the assets path
app.use('/assets', express.static('/assets'));
app.get('/api/users/:id', function(req, res){
// return data for user....
});
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
});
When you reload the page, the request goes to the server side of your application, and it tries to resolve the url but it probably can't, because those routes only exists on the client side of your application.
Also it is a good idea to prefix every server side route with an /api route prefix, so you can easily distinguish between client side and server side routes.
I have been using AngularJS for a few months now. I have been using a Java backend for all of my AngularJS applications. Now I'd like to learn how to program full-stack JavaScript applications. I've never programmed in NodeJS.
The current design of my app has Angular taking care of all the routing, which is what I am most comfortable with. However, I am not sure if that is good design when using NodeJS and Express on the backend. In the past, my backend has been responsible for exposing a REST API that my frontend could leverage, and manipulating JSON data. I didn't use it for anything else.
This is how Angular is managing the routing in my full-stack JS app
(function()
{
angular
.module('passGen', [
'ui.router',
'ngAnimate',
'passGen.generator',
'passGen.registration',
'passGen.tabs',
'passGen.main'
])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider)
{
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'partials/main.html'
})
.state('registration', {
url: '/register',
templateUrl: 'partials/registration.html'
})
.state('products', {
url: '/products',
});
}]);
})();
I want to add user registration functionality to the application. This is where TaffyDB and Node come into play. I'd like the backend to maintain and serve all of the user registration data in order to avoid overloading the frontend.
Right now all I'm trying to do is post some data in NodeJS to the /products route, but it's not doing anything. This is reflected in the comments.
server.js
(function()
{
// modules
var express = require('express');
var path = require('path');
var TAFFY = require('taffy');
var app = express();
app.use(express.static('src/app'));
var products = TAFFY([{
'item':1,
'name':'Shark'
}]);
// I don't think this is necessary
app.get('/#/home', function(req, res)
{
res.sendFile(path.join('/index.html'));
});
// Not doing anything, also doesn't work with the '/products' path
app.post('/#/products', function(req, res)
{
res.send(products);
console.log(products);
});
app.listen(8878);
})();
Perhaps I need to take a deeper look at ExpressJS routing documentation, or refine my Google queries.
I have some questions:
Should I use AngularJS or ExpressJS to handle the routing?
If I can use AngularJS for the routing, then should I be able to use ExpressJS to handle HTTP requests?
Why isn't app.post working in server.js?
I've got my redirect working correctly, the only problem is now all my style sheets are being served as text/html because it's being piped through core.index It only gives me the error for style sheets too not JS. How do I resolve this?
Error:
Resource interpreted as Stylesheet but transferred with MIME type text/html:
application.js
angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider',
function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$locationProvider.hashPrefix('!');
}
])
express.js
app.use(express.static(path.resolve('./public')));
// Globbing routing files
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
var core = require('../app/controllers/core.server.controller.js');
app.get('/*', core.index);
core.server.controller.js
exports.index = function(req, res) {
res.render('index', {
user: req.user || null,
request: req
});
};
core.client.routes.js
// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// Redirect to home view when route not found
$urlRouterProvider.otherwise('/404');
$stateProvider
.state('admin', {
url: '/admin',
templateUrl: 'modules/core/views/home.client.admin.view.html',
});
}
]);
That would not be the correct way to serve static content - images, CSS and javascript files that run on the browser.
Take a look at this article
Basically, assuming that your directory structure is as follows:
-- public
|-- css
|-- img
`-- js
where public is the folder that contains all the sub folders for hosting stylesheets, images etc.
Then, in your nodejs code, where you have the var app = express() code, have the following code after it:
app.use(express.static('public'));
Thus, when the browser encounters a stylesheet declaration such as:
<link rel="stylesheet" href="css/style.css/>
it will make a request to /css/style.css and your express server will then correctly serve the stylesheet.
Have the code app.get("/*", core.index) at the end of all the above code to ensure that it is the last option that the server tries when attempting to match a request path to a request handler.
I want to use angularjs routing, I'm using but it's making extra requests in server side. Anyone know the solution of this problem, or I'm doing something wrong?
Client app.js
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false})
$routeProvider.
when('/', {
templateUrl: '/tpl/main.tmp.html',
controller: 'MainCtrl'
})
.otherwise({redirectTo: '/'})
}])
//routes.js
app.get('/', function(req, res) {
console.log("test")
res.render(__dirname+'/public/tpl/index.html', siteConfig)
})
//output
//test
//test
//test
//test
Files:
models
public
|-css
|-js
|--app.js
|--angular.js
app.js
A few things may cause this, a closer inspection of both request packets might narrow down the cause. Some ideas to check for:
The browser keeps trying to fetch the site favicon because it can't find one
Fetching an image with a # in the URL (i.e. <img src="#"/>)
Meta refresh tag in the HTML
Web browsers may retry requests when the connection is closed before receiving a response