Home > other >  How to rewrite URL in angular?
How to rewrite URL in angular?

Time:04-06

I am new to angular. I am working on ecommerce project. My boss told me that he needs a URL rewrite behavior. For instance.

Website domain is abc.com. All the product is listing on productlisting page

abc.com/productlisting

So when visitor visits a website and click's on women category, the URL must change to

abc.com/productlisting/women

and if visitor clicks on men the URL should be like

abc.com/productlisting/men

Achieving this url from base domain is not an issue. I am using below code to get the current url and then append it with what visitor clicked on.

var route = this.route.snapshot.routeConfig.path;
var newUrl = route   "/"   men;
// abc.com/productlisting/men

or in case of women

var newUrl = route   "/"   women;
// abc.com/productlisting/men

However, when a visitor directly type above URL into search box on web he/she gets 404 page not found, which is understandable as there is no page with that URL in the app-routing.ts file.

So, to overcome this issue I added 2 new routes in app-routing.ts file.

import { Routes, RouterModule } from '@angular/router';
import { IndexComponent } from './components/index/index.component';

import { ProductlistingComponent } from './components/productlisting/productlisting.component';  


const routes: Routes = [
    { path: '', component: IndexComponent },
    { path: 'productlisting', component: ProductlistingComponent },  

    { path: 'productlisting/women', component: ProductlistingComponent },  
    { path: 'productlisting/men', component: ProductlistingComponent },   
 
    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const appRoutingModule = RouterModule.forRoot(routes);

After adding 2 new routes, when a user visit a website with

abc.com/productlisting/women

or

abc.com/productlisting/men

there is no 404 error and user lands on a valid page.

The problem:

Issue is the productlisting page has main filters around 21 and sub filters in each are about 100 . My boss told me that the URL should go to 4 sub paths for example

abc.com/path-01/path-02/path-3/path-04

abc.com/productlisting/women/color/black

path-01: will always be productlisting path-02: there are 6 possibilities: men, women, boys, girls, baby-girls, baby-boys path-03: there are 21 possibilities: color, closure, character, material, neckline etc.... path-04 there are 100 possibilities: black, white, red, collared, beat-neck etc...

So that means for each product I have to define a route in app-routing.ts file,

import { Routes, RouterModule } from '@angular/router';
import { IndexComponent } from './components/index/index.component';
import { ProductlistingComponent } from './components/productlisting/productlisting.component';  


const routes: Routes = [
    { path: '', component: IndexComponent },
    { path: 'productlisting', component: ProductlistingComponent },  

    { path: 'productlisting/women', component: ProductlistingComponent },  

    { path: 'productlisting/women/character', component: ProductlistingComponent },
    { path: 'productlisting/women/closure', component: ProductlistingComponent },
    { path: 'productlisting/women/collar', component: ProductlistingComponent },
    { path: 'productlisting/women/color', component: ProductlistingComponent },
    { path: 'productlisting/women/cuff-style', component: ProductlistingComponent },
    { path: 'productlisting/women/dress-length', component: ProductlistingComponent },
    { path: 'productlisting/women/dress-style', component: ProductlistingComponent },
    { path: 'productlisting/women/embellishment', component: ProductlistingComponent },
    { path: 'productlisting/women/fastening-type', component: ProductlistingComponent },
    { path: 'productlisting/women/feature', component: ProductlistingComponent },
    { path: 'productlisting/women/fit-type', component: ProductlistingComponent },
    { path: 'productlisting/women/garment-care', component: ProductlistingComponent },
    { path: 'productlisting/women/material', component: ProductlistingComponent },
    { path: 'productlisting/women/neckline', component: ProductlistingComponent },
    { path: 'productlisting/women/occasion', component: ProductlistingComponent },
    { path: 'productlisting/women/offer-type', component: ProductlistingComponent },
    { path: 'productlisting/women/pattern', component: ProductlistingComponent },
    { path: 'productlisting/women/season', component: ProductlistingComponent },
    { path: 'productlisting/women/size', component: ProductlistingComponent },
    { path: 'productlisting/women/sleeve-length', component: ProductlistingComponent },
    { path: 'productlisting/women/sleeve-type', component: ProductlistingComponent },
    { path: 'productlisting/women/theme', component: ProductlistingComponent },

    { path: 'productlisting/men', component: ProductlistingComponent },  

    { path: 'productlisting/boys', component: ProductlistingComponent },  
    { path: 'productlisting/girls', component: ProductlistingComponent },  
    { path: 'productlisting/baby-boys', component: ProductlistingComponent },  
    { path: 'productlisting/baby-girls', component: ProductlistingComponent },  
 

   

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const appRoutingModule = RouterModule.forRoot(routes);

Is there any better way to achieve URL rewriting. Because if I do this I can create 1000 routes which will redirect to the same component abc.com/productlisting. I am not sure if this is a way to go. Any help is appreciated.

CodePudding user response:

Use parametrized routes for your first productListing component. You don't need to make 6 routes initially.

So something like below

{ path: 'productlisting/:productCategoryID', component: ProductlistingComponent },

so now when you route (be it from routerLink in html file or router.navigate) pass the id (in your case id is men, women etc)

After this the child routes will come in question (can be done via child modules as well, but your purpose can be fulfilled without it as well). You can search it up but for starters it has children array which defines the child routes defined for your existing URL. Something like this:

{
    path: 'productListing/:Id',
    component: ProductListingComponent,
    children: [
      {path: '', redirectTo: 'abc'},
      {path: 'abc', component: SomeCompoent},
      {path: 'xyz', component: SomeOtherComponent},
    ]
}

In your case you have just one component that changes so maybe you can further parametrized it.

CodePudding user response:

I can suggest you create a base URL abc.com/productlisting that you already have. Step 1: Now, load a child module on it.

Step 2: Create a module that contains components to serve different listings like women, men etc. You can use path-based navigation to these components as filters will be different in every component based on category.

Step 3: Now instead of adding a path you should add the query params to filter and show the listing based on path-03 and path-04. It will be easy to pick the details from query params and pass them to the component filter to get the list and show it.

Step 4: If the above step 3 is not feasible try to create a regex that matches the given list of words for a given path. You can create one listing like an array of words that the path should contain (just thinking out loud).

You can check here and give it a look. Using a regex pattern can solve it easily. You just need to make it for path03 and path04 as they have more patterns to match.

You can also use this approach, but you need to make sure you always have 4 paths.

{path:'productlisting/:id1/:id2/:id3', component: ProductlistingComponent}

I would suggest you create a module as a component that should be lightweight and keep the filter logic in service.

In the component, you can do something like this:

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

constructor(private route: ActivatedRoute) {
  this.route.paramMap.subscribe( params => {
    this.id_1 = params.get('id1') ?? ''; // assign anything
    this.id_2 = params.get('id2') ?? '';
    this.id_3 = params.get('id3') ?? '';
  });
}

This way you can always catch all the path segments and even if one is not available, your filter will run easily.

Open to any suggestions.

  • Related