0

is it possible to achieve all URLs working correctly?

domain.com/account/ (Account component)

domain.com/account/login (Login component)

domain.com/account#resource (Resource component)

working example with app.module.ts, app-routing.module.ts and index.html would be much appreciated

ik00ma
  • 422
  • 6
  • 24

1 Answers1

1

I think you are confusing a Fragment Identifier and Angulars Hash Location Strategy, which are two different things.

A Location Hash is essentially used to tell the browser to go to a particular section on of a page.

Angulars Hash Location Strategy puts a # between the domain and the rest of the route so you don't need to worry about configuring your webserver to re-direct to index when someone hits http://www.my-angular-site.com/some/route. With that example, a web server like IIS will try to load an index.html file from the /some/route folder, which won't exist. In order to achieve the expected behavior, you'd need to include do a URL rewrite to http://www.my-angular-site.com/ which will then load your single page app plus the JS needed to render the DOM for /some/route. If you you use the Hash Location Strategy the URL will be http://www.my-angular-site.com/#/some/route, which means you'll load index.html from the base directory - no url rewrite needed.

Is there a specific reason you're trying to use a Location Hash as a routing mechanism? It probably makes more sense to use something like /account/:resource_id

#1 and #2 are pretty straight forward. I've included how I would handle the resource bit.

export const myRoutes: Routes = [
    {
        path: 'account',
        component: AccountComponent,
        children: [
            {
                path: 'login',
                component: LoginComponent
            },
            
            //This is the better way to load it
            {
                path: ':resourceId',
                component: ResourceComponent
            }
        ]
    }
]

However, if you've got some other requirement that necessitates using the urls you provided, you can access the fragment and conditionally render the component like so:

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'account',
  template: `
    <div>
      <h1 *ngIf="!resourceId">Account</h1>

      <resource *ngIf="resourceId" [resource]="resourceId"></resource>
    </div>
  `
})
export class AccountViewComponent {
  resourceId: string;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.route.fragment.subscribe(frag => {
      this.resourceId = frag;
    });
  }
}

Here's a stackblitz that demonstrates

spots
  • 2,483
  • 5
  • 23
  • 38
  • Hey @spots. I have no control over the server. That's the problem. So `account/resource` returns 404. also I must handle `account/login` path as well. I am going to follow the last solution. Thanks – ik00ma Jul 22 '21 at 19:55