Check to see if a name is present in the URL using Angular2

I'm still in the process of learning angular and typescript, so please forgive me for this question that may seem silly...

Currently, I have a list containing actors. When one of these actors is clicked on, it redirects to a detailed page with a URL structure like this:

localhost:4200/actors

After clicking on an actor, the URL changes to something like:

localhost:4200/actors/Jonas

Now, my goal is to verify if the chosen actor actually exists. If a user manually enters a random name in the URL, I want to redirect them back to the /actors page instead of displaying a blank page.

This is a snippet of how my component looks:

actor: Actor;
constructor(
    private actorService: ActorService,
    private route: ActivatedRoute,
    private location: Location
) {}
ngOnInit(): void {
    this.route.params.subscribe(() => {
        if (/* code to check if actor.name exists in the url */) {
            this.route.paramMap.switchMap((params: ParamMap) =>
                this.actorService.getActor(params.get('name')!))
                .subscribe(actor => this.actor = actor);
        } else {
            this.location.go('/actors');
        }
    });
}

Does anyone have any insights on how I can accomplish this?

Answer №1

It's not recommended to nest the subscribe call. A more efficient approach would be using mergeMap or switchMap for handling nested asynchronous operations.

One way to retrieve the name parameter from the route path is shown below:

constructor(private router: Router,
           private actorService: ActorService,
           private route: ActivatedRoute,
           private location: Location)
{}
ngOnInit(): void {
    this.route.params
    .mergeMap(
       (params: Params) => {
          if(params['name']) {
             return this.actorService.getActor(param['name']);
          } 
          return Observable.of(false);
       }
    )
      .subscribe((actor: any) => {
        if (actor ) {
             this.actor = actor;
        }else {
            this.router.navigate(['/actors']);
        }
    });
}

Answer №2

When using Angular, you can leverage a feature called Resolver to fetch data before navigating to a specific route. A Resolver is essentially a service that implements the Resolve interface from @angular/router.

For instance, you can create a Resolver like this for handling actors:

@Injectable()
export class ActorResolver implements Resolve<Actor> {
  constructor(private actorService: ActorService, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Actor> {
    let name = route.paramMap.get('name');
    return this.actorService.getActor(name).pipe(take(1)).map(actor => {
      if(actor) { // check if actor exists else redirect
        return actor;
      } else {
        this.router.navigate(['/actors']);
        return null;
      }
    });
  }
}

To use the Resolver, make sure to add it to the providers list in the module file and specify it in the route configuration:

{ 
  path: ':name',
  component: ActorDetailsComponent,
  resolve: {
    actor: ActorResolver
  }}
}

In your component, you can access the resolved data like this:

constructor(private route: ActivatedRouteSnapshot) {
  this.actor = this.route.data.actor;
}

For more information on route resolvers, refer to the official documentation.

Answer №3

Give this a shot

this.route.params.subscribe( param => {
            //verify if there is a value in the name parameter
        if (param['name') {
            // retrieve the data
              this.actorService.getActor(param['name'])
              .then( actor =>{
                    //if the data does not exist, redirect to /actors
                   if(!actor)
                     this.location.go('/actors');
               })
        }else {
            this.location.go('/actors');
        }
    });

Answer №4

//below is the script

this.route.params.subscribe( params => {
        if (params['name']) {
           //place your code here
        }else {
            this.location.go('/actors');
        }
    });

Answer №5

character: Character;
constructor(
    private characterService: CharacterService,
    private route: ActivatedRoute,
    private location: Location
) {}
ngOnInit(): void {
    this.route.params.subscribe((params) => {
        if (params['name']) {
            this.characterService.getCharacter(params.get('name')!))
                .subscribe(character => this.character = character);
        }else {
            this.location.go('/characters');
        }
    });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it acceptable to include a @types library as a regular dependency in the package.json file of a Typescript library?

Should the library also be compatible with Typescript projects? I am developing a Typescript library that utilizes node-fetch and @types/node-fetch, which will be shared through an internal NPM registry within the company. If I only include @types/node-f ...

transmit data from Node.js Express to Angular application

I am making a request to an OTP API from my Node.js application. The goal is to pass the response from the OTP API to my Angular app. Here is how the API service looks on Angular: sendOtp(params): Observable<any> { return this.apiService.post(&q ...

Trouble arises in TypeScript when defining a class - SyntaxError crops up

When I try to declare a class, I encounter an error: // The code below is from my test1.ts file class WDesign { wModel: string; wQuer: string; } let logWDesign = (wd : WDesign) => { console.log(wd.wModel + " " + wd.wQuer); } let wd1 : WDe ...

Cannot display data in template

After successfully retrieving JSON data, I am facing trouble displaying the value in my template. It seems that something went wrong with the way I am trying to output it compared to others. My function looks like this, getUserInfo() { var service ...

Exploring Angular4: Utilizing HttpClient with HttpParams for Passing Object Values in httpParams.set()

I'm facing an issue with handling a more complex key value pair. What if I need to set a value as an object? This is the problem I am encountering: const includeStr = JSON.stringify({include: 'match-timeline-events'}); const params: HttpPa ...

Issue with side panel not closing when clicked outside on IOS devices using Angular 6

On all devices except for IOS, the layout side panel is closing when clicking on the DOM: @ViewChild('closeContainer') LeftMenuObj; @HostListener('document:click', ['$event']) clickedOutside($event) { if (this.L ...

Utilizing the params property of ActivatedRouteSnapshot to dynamically populate data within a component

Picture a scenario where we have a single component that needs to be filled with data based on different URL parameters. Consider the following URL patterns: 1. http://localhost:4200/venues/5760665662783488 2. http://localhost:4200/users/2gjmXELwGYN6khZ ...

Jsx Component fails to display following conditional evaluations

One issue I am facing is having two separate redux stores: items (Items Store) quotationItems (Quote Items). Whenever a product item is added to quotationItems, I want to display <RedButton title="Remove" />. If the quotationItems store i ...

Having trouble locating the name 'it' in Jest TypeScript

After setting up Jest in React + TypeScript, I encountered an error when trying to run a test using the command npm test. The error message displayed was: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try ` ...

Guidelines for Nestjs class-validator exception - implementing metadata information for @IsNotIn validator error handling

I have a NestJs data transfer object (dto) structured like this import { IsEmail, IsNotEmpty, IsNotIn } from 'class-validator'; import { AppService } from './app.service'; const restrictedNames = ['Name Inc', 'Acme Inc&ap ...

Creating a Dynamic Form in Angular 4 with Multiple Components to Easily Submit Data

Just starting to learn angular 4 and I have a question. I've got a page with 3 sections, each section is its own form: Section 1 - Basic info first name last name email Section 2 - Contact info address city state zip Section 3 - Order info Order i ...

An issue occurred with building deployments on Vercel due to a typing error

When attempting to deploy my build on Vercel, I encountered an error. The deployment works fine locally, but when trying to build it on vercel, the following error occurs: [![Type error: Type '(ref: HTMLDivElement | null) => HTMLDivElement | null&a ...

"I am experiencing an issue with the PrimeNG year picker as it is unable

My goal was to set up a simple PrimeNG calendar with just a year picker. I followed the implementation instructions from the documentation: <p-calendar inputId="year" [(ngModel)]="date1" view="year" dateFormat=" ...

An error occurred within Angular 8 while attempting an HTTP post request, as it was unable to access the 'message' property of

After conducting a search on Stack Overflow, I found a similar question that relates to my issue. Login OTP Component: onSubmitValidOTP() { this.authenticationService.ValidOTP(this.fo.OtpControl.value, username, role) .pipe(first ...

Filtering JSON array data in Typescript can help streamline and optimize data

Recently diving into Angular, I am facing a challenge with filtering data from a JSON array. My goal is to display names of items whose id is less than 100. The code snippet below, however, is not producing the desired result. list : any; getOptionList(){ ...

Packaging an NPM module to enable unique import paths for Vite and Typescript integration

Is there a way to package my NPM module so that I can use different import paths for various components within the package? I have looked into webpack solutions, but I am working with Vite and TypeScript. This is the structure of my package: - src - ato ...

Creating a Persistent Top Navigation Bar using Bootstrap and Angular

I am struggling to implement a fixed top navbar in Angular. The structure of my main app.component template is as follows: <page-header></page-header> <router-outlet></router-outlet> The bootstrap navbar is included within my ...

Tips for conducting key down event testing on a material ui MenuList element utilizing react-testing-library

Looking to test the key down event on my MenuList component. Component: import MenuItem from '@material-ui/core/MenuItem'; import MenuList from '@material-ui/core/MenuList'; import * as React from 'react'; export default fu ...

Despite having the same versions for Angular and Angular CLI, the build process using 'ng build'

After running ng v, the output shows: Angular CLI: 9.1.13 Node: 12.22.12 OS: win32 x64 Angular: 9.1.13 Strangely, attempting to execute ng build resulted in the following error: This version of CLI is only compatible with Angular versions ^13.0.0 || ^13. ...

Steps to create a fixed pattern background image with a customizable background color based on the content within a div element

I am seeking guidance on how to create a single page application using Angular that features a fixed background image (such as a white pattern) in the BODY tag. However, I would like the ability to change the color behind this image depending on the conten ...