What is the reason behind In-memory-web-api not generating an ID?

While I have successfully implemented the GET, PUT, and DELETE methods using InMemoryDbService to simulate an API, I am facing issues with the CREATE method. It seems like the ID is not being generated in the route to display my add form. The error message displayed in the console is:

"url: 'api/pokemons/NaN'" and body : {error: "pokemons" with id = 'NaN' not found"

To keep things concise, I have omitted showing the mock-pokemon-list.ts file which simply consists of an array of data. Additionally, I have removed the methods that are functioning correctly from my files for clarity and ease of reading. I have already attempted to resolve this issue by referring to this topic on Stack Overflow: why genID() method in In-memory-web-api does not generate an ID? ... I hope my query is comprehensible and straightforward. Apologies for the length of the files. Thank you!

pokemon.module.ts (routes)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { PokemonService } from './pokemon.service';
import { FormsModule } from '@angular/forms';
import { PokemonFormComponent } from './pokemon-form/pokemon-form.component';
import { AddPokemonComponent } from './add-pokemon/add-pokemon.component';

const pokemonRoutes: Routes = [
  { path: 'pokemon/add', component:AddPokemonComponent},
  
]
    
@NgModule({
  declarations: [
    PokemonFormComponent,
    AddPokemonComponent
    
  ],
  imports: [
    CommonModule,
    FormsModule,
    RouterModule.forChild(pokemonRoutes)
  ],
  providers: [PokemonService],
})
export class PokemonModule { }


in-memory-data-service.ts (we import data from mock-pokemon-list.ts which uses pokemon.ts class just after)

import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { POKEMONS } from './pokemon/mock-pokemon-list';

@Injectable({
  providedIn: 'root'
})
export class InMemoryDataService implements InMemoryDbService {

  createDb() {
    const pokemons= POKEMONS;
    return { pokemons };
  }
}

pokemon.ts

export class Pokemon {
    id:number;
    name:string;
    hp:number;
    cp:number;
    picture:string;
    types:string[];
    created:Date;

  constructor(
    name:string = 'Enter a name...',
    hp: number = 100,
    cp: number = 10,
    picture: string = 'https://assets.pokemon.coom/assets/cms2/img/pokedex/detail/xxx.png',
    types:string[] = ['Normal'],
    created: Date = new Date()
  ) {
    this.name=name;
    this.hp=hp;
    this.cp =cp;
    this.picture = picture;
    this.types = types;
    this.created = created;
  }
     
  
}

imports and add method in pokemon.service.ts

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Pokemon } from './pokemon';
import { catchError, Observable,of, tap } from 'rxjs';


@Injectable()
export class PokemonService {

  constructor(private http: HttpClient){}

 addPokemon(pokemon:Pokemon):Observable<Pokemon>{
  const httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json'})
  };
  return this.http.post<Pokemon>('api/pokemons', pokemon, httpOptions).pipe(
    tap((response)=> this.log(response)),
    catchError((error)=>this.handleError(error, null))
  )
 }
 
  private log(response: any) {
    console.table(response);
  }
  private handleError(error: Error, errorValue: any) {
    console.error(error);

    return of (errorValue);
  }
  
}

add-pokemon.component.ts (a component which uses pokemon-form just below)

import { Component, OnInit } from '@angular/core';
import { Pokemon } from '../pokemon';

@Component({
  selector: 'app-add-pokemon',
  template: `
    <app-pokemon-form [pokemon]="pokemon"></app-pokemon-form>
  `,
})
export class AddPokemonComponent implements OnInit {

  pokemon:Pokemon;

  ngOnInit(): void {
    this.pokemon = new Pokemon();
  }

}

pokemon-form.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Pokemon } from '../pokemon';
import { PokemonService } from '../pokemon.service';

@Component({
  selector: 'app-pokemon-form',
  templateUrl: './pokemon-form.component.html',
  styleUrls: ['./pokemon-form.component.css']
})
export class PokemonFormComponent implements OnInit {

  @Input() pokemon:Pokemon;
  types: string[];
  isAddForm:boolean;

  constructor(
    private router:Router,
    private pokemonService: PokemonService
  ) { }


  ngOnInit()  {

    this.isAddForm = this.router.url.includes('add');
  }
    

  onSubmit() {
    if(this.isAddForm) {
      this.pokemonService.addPokemon(this.pokemon)
      .subscribe((pokemon: Pokemon)=> this.router.navigate(['/pokemon', pokemon.id]));
    }else {
      this.pokemonService.updatePokemon(this.pokemon)
      .subscribe(() => this.router.navigate(['/pokemon', this.pokemon.id])); 
    }
    
  }
}

my button which initiates the action

<a class="btn-floating btn-large waves-effect waves-light red z-depth-3"
  style="position: fixed; bottom: 25px; right: 25px;" routerLink="/pokemon/add"> + </a>

Answer №1

After reviewing your code, it appears that when you navigate to /pokemon/add, you should be using the AddPokemonComponent instead of the DetailPokemonComponent.

const pokemonRoutes: Routes = [
  { path: 'edit/pokemon/:id', component: EditPokemonComponent},
  { path: 'pokemons', component: ListPokemonComponent },
  { path: 'pokemon/:id', component: DetailPokemonComponent},
  { path: 'pokemon/add', component: AddPokemonComponent},
]

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

What is the best way to output data to the console from an observable subscription?

I was working with a simple function that is part of a service and returns an observable containing an object: private someData; getDataStream(): Observable<any> { return Observable.of(this.someData); } I decided to subscribe to this funct ...

Encountering a Typescript error with Next-Auth providers

I've been struggling to integrate Next-Auth with Typescript and an OAuth provider like Auth0. Despite following the documentation, I encountered a problem that persists even after watching numerous tutorials and mimicking their steps verbatim. Below i ...

Encounter the error message "Unable to resolve all parameters" after including the Interceptor

Currently, I am in the process of implementing HttpInterceptor functionality. However, upon adding it to @NgModule, I encountered the following error message in Chrome: Uncaught Error: Can't resolve all parameters for JwtInterceptor: (?, ?). at s ...

Tips for mocking Dependent Modules in Jasmine when dealing with a plethora of dependencies in Angular 9

Looking to create a unit test for a component within an Angular project. The main component has 5-6 dependencies and extends another class with around 7 additional dependencies. What is the most effective method to set up the TestBed for this component? ...

Issue with Ng test: The type definition file for '@angular/localize' cannot be located

When upgrading from Angular 14 to 17, I ran into an issue with the ng test command. It seems to be malfunctioning now. Error: PS C:\ForAngular17\src\ng\cat-ng> ng test One or more browsers configured in the project's Browsersli ...

Retrieve the value of [innerHTML] from a subcomponent

I am trying to retrieve the [innerHTML] from a child component Greetings everyone There is a component named 'contact-us' containing the following field. <div [innerHTML] = "legalContent.disclaimer"></div> I have included ...

Formatting numbers in Angular 2 to include a space every three zeros in a money amount

Let's say I have the number 30000 and I want to format it as 30 000. What method should I use to achieve this? Here are more examples: 300000 -> 300 000, 3000000 -> 3 000 000. Just to clarify, this is not about using dots or commas, but rather reco ...

Having trouble directing my attention towards a Mat card when using viewchildren in Angular

My current challenge is trying to focus on a specific card from a list of mat cards Despite my efforts, I keep encountering an error that reads: Cannot read property 'focus' of undefined Access the code on StackBlitz The desired functionali ...

Error in Angular 4: Undefined property 'replace' causing trouble

I've been trying to use the .replace() JavaScript function in Angular 4 to remove certain characters from a string. Here is the code snippet from my component: @Component({...}) export class SomeComponent implements OnInit { routerUrl: string = &apo ...

Guide to defining a typescript class property using an index signature

type TField = { field1: string; field2: boolean; field3: TMyCustom; } class Test1 { // I opt for using TypeScript's index signature to declare class fields [key: keyof TField]: TField[typeof key] // Instead of individually declaring each ...

Is Angular's ngOnChanges failing to detect any changes?

Within one component, I have a dropdown list. Whenever the value of the dropdown changes, I am attempting to detect this change in value in another component. However, I am encountering an unusual issue. Sometimes, changing the dropdown value triggers the ...

Angular Leaflet area selection feature

Having an issue with the leaflet-area-select plugin in my Angular9 project. Whenever I try to call this.map.selectArea, VSCode gives me an error saying that property 'selectArea' does not exist on type 'Map'. How can I resolve this? I& ...

What is the meaning of boolean true in a Firestore query using TypeScript?

Currently, I am facing an issue with querying Firestore in Angular 8 using AngularFire. While querying a string like module_version works perfectly fine as shown in the code snippet below, the problem arises when attempting to query a boolean field in Fire ...

The 'src' properties in nextjs/image are of different types and therefore cannot be used interchangeably

I'm currently using React Dropzone to upload multiple images in my basic application. To display the types of images that are being dropped, I created a separate component with TypeScript. However, Next.js is throwing an error when it comes to the ima ...

Utilizing dependency injection for nested services in Angular 2

I am designing a custom Broadcast system to create and utilize EventEmitters dynamically within the user context by injecting an EmitterService. @Injectable() export class BroadcastService implements OnInit { private _emitters: { [channel: string]: Ev ...

Angular 5 and the world of HTTP connections

As I embark on my journey of creating my very first Angular 5 application, one of the key components is its interaction with the Java Rest Web Services that I have developed using Spring Boot. The foundation of this integration lies in the following RESTfu ...

Controlling the visibility of an element in Angular2 by toggling it based on an event triggered by a

Within my component, there is a child element: <fb-customer-list (inSearchMode)="listIsInSearchMode = event$"></fb-customer-list> This child element emits an event that contains a boolean value to indicate when it changes modes. In the paren ...

Searching for a way to access the HTTP request header using ReactJS?

Can anyone assist me in retrieving the request header's cookie? I have searched extensively but haven't found a satisfactory document. Please share with me a reliable solution. ...

Creating an Angular 2 component library that is compatible with both webpack.js and system.js: A guide

This is my first venture into creating an Angular 2 library. So far, it consists of a collection of components. I am aiming to make this library compatible with both Webpack and SystemJS. I have successfully written the code for the first component to be c ...

Pressing the confirm button will close the sweet alert dialog

When pressing the confirm button, the swal closes. Is this the intended behavior? If so, how can I incorporate the loading example from the examples? Here is my swal code: <swal #saveSwal title="Are you sure?" text ="Do you want to save changes" cancel ...