Ionic2 and routing and hotlinking


#1

Hello,

We recently started exploring Ionic2/ng2 and so far it looks like it can meet most of our requirements. One issue I’ve been running into and haven’t been able to figure out is routing. In our case, we plan to re-use the code base for desktop browsers as well as device browsers, which means users may want to bookmark certain routes.

For example, our users may likely want to bookmark the following example url: www.my-site-about-trees.com/tree/leaf1
Our plan is to host the ionic2 codebase on AWS S3 and after trying out several different approaches with angular’s PathLocationStrategy and HashLocationStrategy I’m unable to get a bookmark to work correctly. The route is not recognized.

I understand that 1) ng2 routing is still a work in progress, 2) Ionic2 navigation is supposed to be handled via NavController methods (are RouteConfig and LocationStrategy constructs supported in Ionic2?), and 3) a typical situation, the server would need to serve up the index.html page first and then the client side would handle the route, but how do I accomplish this if the code is on S3?

I also explored ng2 AuxRoute, but that doesn’t seem to work either.

Thanks for your help!

Denis


#2

This is a server configuration issue; it has nothing to do with Angular. You need to configure the server to return index.html for all paths other than static resources. Then you handle the routing on the client after index.html bootstraps Angular. I’m not familiar with what configuration AWS S3 provides, but most major webservers (nginx, Apache, IIS) can be configured for this.


#3

Hi erg1,

Thanks for your response, this makes sense. It looks like the following SO article has a solution for the S3 scenario.

I just tried it and it appears to work.

Thanks!

Denis


#4

Hi erg1,

I have index.html being served up for all routes on s3 and separately using a node express server locally. However, when I try to use both PathLocationStrategy and HashLocationStrategy, I’m unable to have the page associated with a route to load. In the example below; I want to be able to go to www.mysite.com/style-guide directly. It’s not clear what I’m missing.

app.ts:

@App({
    templateUrl: 'build/app.html',
    providers: [
        HTTP_PROVIDERS,
        ROUTER_PROVIDERS,
        provide(LocationStrategy, { useClass: HashLocationStrategy })//,
        //HashLocationStrategy//,
        //provide(APP_BASE_HREF, {useValue: '/' + location.pathname})
    ],
    directives: [ROUTER_DIRECTIVES]
})

@RouteConfig(
    [
      {
        path: '/', as: 'Home', component: HomePage
      },
        //async style-guide route
        //new AsyncRoute({path: '/style-guide', loader: () => Promise.resolve(StyleGuidePage), name: 'StyleGuide'}),
        { path: '/style-guide', as: 'StyleGuide', component: StyleGuidePage}
      ]
)
export class MyApp {
    rootPage:any = HomePage;

    constructor(platform:Platform) {
        platform.ready().then(() => {
            StatusBar.styleDefault();
        });
    }
}

index.html contains <base href="/">

On a related note, I really would like to use RouterLink to faciliate navigation rather than having to use the NavController.push method. Is there a good example that I can refer to?

I’m currently on 2.0.0-beta.24

Thanks!

Denis


#5

hello Denis,

Sorry I didn’t notice your followup and can’t be more helpful…I’m in a similar boat. I actually had to disable Angular routing because it was choking on a hash fragment being set by the Google OAuth dance. Like you, I wanted to replace the Ionic stack-based navigation with meaningful, bookmarkable ReSTful URLs, but that goal seems incompatible with a functional application that meets my other requirements. I believe dropping the stack-nav may also break Ionic’s transition animations, which would then likely have to be managed manually.

So for now I regretfully have to recommend avoiding Angular routing in Ionic 2. There might be a way to combine both Angular and Ionic nav, but I expect it would be very ugly and fragile.

It’s too bad since I was hoping to have a mobile web app running the same code as the device-deployed version with a simple branch to use Cordova’s InAppBrowser for OAuth on devices.

I’ll try to post a followup if I come up with any new insights.

(my followup follows:)

I just tried with the latest Ionic version (2.0.0-beta.25), and the problems I was having before with Angular routing appear to have been sorted out. I was on a pretty old (at least a month or so, I think it was beta.17) version. The routing seems to be working great now from my limited testing. I’ve also found the transition animations work great automatically with Angular routing! Great job, Ionic guys!

So back to your post, Denis…I don’t think you are supposed to use both PathLocationStrategy and HashLocationStrategy…it should be one or the other, depending on whether you want or need hash-URL syntax (like for older browsers).

I think I read that Path (“html5-style”) was the default strategy. I have it working without setting up any configuration other than the imports and the @RouteConfig. I’m also injecting the Router component, which allows you to navigate dynamically from your code without using the Ionic Nav stack. I’m not sure how much help it might be, but here’s my current app.ts. I can’t seem to get the code formatting working in this editor. Decided to upload a screenshot instead.

Then navigating is as simple as

// navigate to /item/:id route: this._router.navigate(['Item', { id: item.id }]);


#6

Hi erg1,

Thanks for your follow up! I noticed that the router.navigate method updates the browser location bar, but doesn’t load the corresponding page component. In my case, I have a link to a style guide page from the home page, and I have to use the router.navigate in conjunction with nav.push or nav.setRoot where nav is an instance of NavController.

this._router.navigate(['Styleguide']);
nav.push(StyleGuidePage);

After updating ionic-angular to 2.0.0-beta.6, most of my routes work, except for one. I receive a “Maximum call stack size exceeded” exception and I can’t for the life of me figure out why this one route has an issue. It’s really bizarre.

Thanks again for your help!

Denis


#7

Figured out infinite recursion issue. I had another set of ion-tabs in the style guide page. Took me a while to sort that out.


Using Ionic 2 as a browser based web application vis-à-vis --no-cordova not recommended?
#8

Well good luck…I’m starting to lean away from Angular routing again, after all. The documentation currently ranges between limited and non-existent, from what I’ve seen. And there seem to be too many problems mixing Angular routing with Ionic nav.

It looks like for me Ionic is automatically handling the Angular navigate event and adding a view to the nav stack. At first I thought that was cool (unexpected automatic transitions), but now I’m facing issues with the auto-generated Back button. It apparently doesn’t use the Angular Router to go Back, but just pops the Ionic nav stack(?). Unfortunately that means that Router parameters (e.g. drill-down id) are not cleared (only from the URL, not from the Router) when they should be, and querying the Router’s currentInstruction yields the last route used for an explicit navigate(), disregarding the nav pop, so is unreliable. Since the Router is a singleton, it’s parameters can get out of sync with the view. This is actually a general problem I’ve found with the Ionic Nav stack concept…it doesn’t seem to cache models / controller instances, but only the rendered HTML. So one may go “Back” to the previous “Page”, but the data does not revert without using some sort of per-instance cache service. This may be related to using self-referencing components and I may need to study things in more depth, but it is getting frustrating with such limited documentation.


#9

Good luck to you too, good sir. I also just discovered the currentInstruction property, but will keep an eye out for the issues you ran into regarding the RouteParams.

Cheers.