I am trying to make Angular routing in my AngularJS/Angular hybrid application.
I created app-routing.module.ts file :
import { ModuleWithProviders } from "#angular/core";
import { Routes, RouterModule, ExtraOptions } from '#angular/router';
import {SignInComponent} from "./modules/login/components/sign-in/sign-in.component";
import {ActivationComponent} from "./modules/login/components/activation/activation.component";
const routes: Routes = [
{
path: 'sign-in',
component: SignInComponent
},
{
path: 'activation',
component: ActivationComponent
},
{
path: '',
pathMatch: 'full',
redirectTo: '/activation'
},
{
path: '**',
pathMatch: 'full',
redirectTo: '/activation'
}
];
export const routingModule: ModuleWithProviders = RouterModule.forRoot(routes);
in app.module.ts I added routingModule to "imports" array and in app.component.html I added :
<button (click)="goto('sign-in')">go to home</button>
<button (click)="goto('activation')">go to product</button>
<router-outlet></router-outlet>
When insight by index.html i am using just Angular it works perfectly
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
But when I am adding my AngularJS code just adding
this.upgrade.bootstrap(document.body, ['app']);
my current Angular routing instead reload content of "router-outlet" tag, reloads completely the page. If I remove
this.upgrade.bootstrap(document.body, ['app']);
it works fine.
Does anybody had some similar issues and maybe someone can propose some scenario how to make Angular routing work appropriately insight hybrid AngularJS/Angular application?
Thanks
It looks like you have not configured the AngularJS and Angular Router in the correct way, please verify the below steps-
Default route (.otherwise) should be removed from AngularJS routing.
Implement the 'UrlHandlingStrategy' interface as a part of Angular router config settings to handle the routing for specific URLs. This will avoid the Angular router conflict with AngularJS router-
export class Ng1Ng2UrlHandlingStrategy implements UrlHandlingStrategy {
shouldProcessUrl(url: UrlTree): boolean {
return url.toString().startsWith('/ng/');
}
extract(url: UrlTree): UrlTree { return url; }
merge(newUrlPart: UrlTree, rawUrl: UrlTree): UrlTree { return newUrlPart; }
}
Add above class (Ng1Ng2UrlHandlingStrategy) as a provider in the root module for URL handling strategy-
providers: [
{ provide: UrlHandlingStrategy, useClass: Ng1Ng2UrlHandlingStrategy }
]
Add both AngularJS and Angular outlet/directive in the app component html
<router-outlet></router-outlet>
<div class="ng-view"></div>
Hash based routing will work but setUpLocationSync(upgrade) is required to support the html 5 based routing in the hybrid app. Please update the main.ts file like below-
upgrade.bootstrap(document.body, ['app']);
setUpLocationSync(upgrade);
Related
I have downgrade a component written in Angular2 + Typescript. Now I want to use it in simple angular 1 app, But the js file compiled from Typescript is using 'import' and I get from browser it is not supported. What I have missed?
This is a simple angular 2 componenet:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'hello-world',
template: `
<p>
hello from angular 2!
</p>
`,
styles: []
})
export class HelloWorldComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
import * as angular from 'angular';
import { downgradeComponent } from '#angular/upgrade/static';
angular.module('dannyApp', [])
.directive(
'helloWorld',
downgradeComponent({component: HelloWorldComponent}) as angular.IDirectiveFactory
);
This is the simple angular1 app tring to use this angular 2 component above:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="dist\out-tsc\app\hello-world\hello-world.component.js"></script>
<script>
angular.module('app', [])
.controller('FrameController', ['$injector', function($injector) {
var vm = this;
vm.message = 'Hello from angular 1';
}]);
</script>
<title>Title</title>
</head>
<body ng-app="app">
<div id="body">
<div ng-controller="FrameController as vm">
{{vm.message}}
</div>
<!-- the angular 2 componenet -->
<hello-world></hello-world>
</div>
</body>
</html>
The browser error:
Uncaught SyntaxError: Unexpected token import
on the line:
import { Component } from '#angular/core';
Make sure you have compiled your Typescript component to ES5.
Your code looks like ES6/Typescript.
Check your tsconfig.json and make sure target: "es5".
I am learning Angular 2 from the official tutorial. I have just completed the latest routing tutorial. What keeps bothering me is that I am able to click through to the path till the detail level which is something like 'http://domainname:portnumber/crisis-center/11' where 'crisis-center' is a subpath and '11' is the id passed in a parameter.
what I found is if I navigate from the root path which is 'http://domainname:portnumber', then I could go through to the detail page without any trouble. But if I open a new window and directly visit the detail view page then it gives me error says
which I believe is a failure of loading the loading 'js' files.
I have already had the base ulr tag
in the index.html page
<html>
<head>
<title>Tour of Heroes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<base href="/">
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
and here is my path settings
import {RouterConfig} from '#angular/router';
import {CrisisDetailComponent} from './crisis-detail.component';
import {CrisisListComponent} from './crisis-list.component';
import {CrisisCenterComponent} from './crisis-center.component';
import {CrisisAdminComponent} from './crisis-admin.component';
import {AuthGuard} from '../auth.guard';
export const CrisisCenterRoutes: RouterConfig = [
{
path: '',
redirectTo: '/crisis-center',
terminal: true
},
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{ path: 'admin', component: CrisisAdminComponent, canActivate: [AuthGuard] },
{ path: ':id', component: CrisisDetailComponent },
{ path: '', component: CrisisListComponent }
]
}
]
Has anyone had similar issue and fixed it?
Thanks
I believe you are missing one tiny line in your main index.html:
<base href="/">
as mentioned here https://angular.io/docs/ts/latest/guide/router.html#!#base-href
I have a setup to use webpack to manage all my assets. it works fine. Now I plan to use react-intl version 2 to support multiple languages.
I have managed to make components defined in package 'react-intl' work,
import {IntlProvider, FormattedNumber, FormattedPlural} from 'react-intl';
class App extends Component {
constructor(props) {
super(props);
this.state = {
name : 'Eric',
unreadCount: 1000,
};
}
render() {
const {name, unreadCount} = this.state;
return (
<p>
Hello <b>{name}</b>, you have {' '}
<FormattedNumber value={unreadCount} /> {' '}
<FormattedPlural value={unreadCount}
one="message"
other="messages"
/>.
</p>
);
}
}
But I can't figure out what's the correct way to load locale file through webpack and refer them in component. Since the package has breaking upgrade recently, there is no much documentation about it either. the wiki page is empty for now
https://github.com/yahoo/react-intl/wiki
I wonder What's the correct way to do this?
xiopang,
I just wrote a webpack plugin based around the translations example from react-intl v2. Hopefully it works for you: https://gist.github.com/marr/95f7a8a3f5529e7e668048548198b9eb
the webpack config plugins then look like:
new TranslateWebpackPlugin(),
new HtmlWebpackPlugin({
template: 'index.hbs', // Load a custom template
inject: 'body', // Inject all scripts into the body
chunks: [ 'app' ],
app: true
}),
and index.hbs:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.App = <%= htmlWebpackPlugin.options.app %>
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
I'm trying to setup routing inside my application, but am getting following error in the console:
angular2-polyfills.js:138 Error: XHR error (404 Not Found) loading http://localhost:9000/angular2/router.js(…)
here is my boot.ts
// -- Typescript typings -------------------------------------------------------
/// <reference path="../typings/jquery.d.ts" />
/// <reference path="../typings/jqueryui.d.ts" />
//Imports ----------------------------------------------------------------------
import {Component, enableProdMode} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {
ROUTER_DIRECTIVES,
ROUTER_PROVIDERS,
Router,
RouteConfig,
} from 'angular2/router';
// -- Application Imports ------------------------------------------------------
import {NavbarComponent} from './components/navbar.component';
import {HomePage} from './pages/home.page';
// -- Enable production module -------------------------------------------------
enableProdMode();
// -- Component ----------------------------------------------------------------
#Component({
selector: 'main-app',
directives: [ ROUTER_DIRECTIVES, NavbarComponent ],
template: `
<app-navbar></app-navbar>
<router-outlet></router-outlet>
`
})
// -- Routing ------------------------------------------------------------------
#RouteConfig([
{ path: '/', name: 'root', redirectTo: ['/Home'] },
{ path: '/home', name: 'Home', component: HomePage }
])
// -- Class --------------------------------------------------------------------
export class MainApp {
constructor(public router: Router) {}
}
// -- Bootstrap for application ------------------------------------------------
bootstrap(MainApp, [
ROUTER_PROVIDERS
]);
and index.html -----
<!doctype html>
<html lang="en">
<head>
<base href="/">
<meta charset="UTF-8">
<title>Angular2 starter</title>
<!-- Application css -->
<link href="dist/libraries/bundle.css" rel="stylesheet"></link>
<link href="dist/styles/main.css" rel="stylesheet"></link>
</head>
<body>
<main-app>Loading...</main-app>
<!-- Application js -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="dist/libraries/bundle.js"></script>
</body>
<!-- ES6-related imports -->
<script src="/node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="/node_modules/es6-shim/es6-shim.min.js"></script>
<script src="/node_modules/systemjs/dist/system.js"></script>
<script>
//configure system loader
System.config({defaultJSExtensions: true});
</script>
<script src="/node_modules/rxjs/bundles/Rx.js"></script>
<script src="/node_modules/angular2/bundles/angular2.min.js"></script>
<script>
//bootstrap the Angular2 application
System.import('dist/app/boot').catch(console.log.bind(console));
</script>
</html>
You are missing a script router.dev.js which is not shown very clearly in a lot of places and examples.
<script src="/node_modules/angular2/bundles/router.dev.js"></script>
I am learning to implement require.js to load the necessary javascript files. I am able to load java script files using require.js which in replace of <script> tags. Even though I am able to load the js files, the content inside the files are not accessible and getting the error saying 'CarApp module not found'. How would this makes the difference?
My index.html where I load require.js
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
<link rel="stylesheet" href="/vendor/bootstrap-2.3.1/css/bootstrap.css" media="screen">
<link rel="stylesheet" href="/css/style.css" media="screen">
<script src="/vendor/angularjs-1.0.5/angular.min.js"></script>
<script src="/vendor/angularjs-1.0.5/angular-resource.min.js"></script>
<script data-main="/js/main" src="/js/require.js"></script>
<div ng-app="CarApp" class="containr">
<div ng-view>
<!-- partial will go here -->
</div>
</div>
/js/main.js
requirejs.config({
paths: {
controllers: './controllers',
app: './app'
}
});
requirejs(['controllers', 'app'],
function (controller, app) { });
/js/app.js
var CarApp = angular.module('CarApp', ['ngResource'])
CarApp.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {controller: ListCtrl, templateUrl: '/partials/list.html'})
.otherwise({redirectTo: '/'})
$locationProvider.html5Mode(true)
})
After loading the app.js file using require.js, it is not able to access 'CarApp' module inside app.js. why is this happening? How can I access 'CarApp module' through main.js.
Your files loaded with RequireJS are not loaded on the page ready event, the time that Angular tries to bootstrap. That is why the CarApp module is not found.
You should bootstrap Angular manually (ref):
Remove the ng-app directive, replace it with an id:
<div id="mainContainer" class="containr">
Bootstrap manually in main.js:
requirejs(['controllers', 'app'], function(controller, app) {
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('mainContainer'), ['myApp']);
});
});
Also check out angular-require-lazy for some, potentially useful, ideas.