Struggling to make angular-in-memory-web-api 0.6.1 function properly despite following the tutorial steps

I recently went through the steps outlined in a tutorial on https://angular.io/tutorial/toh-pt6 to create a dashboard display for my specific project. Everything worked smoothly with a local mock, but I encountered issues when I switched to using the in-memory web API.

The error that keeps popping up is shown here: https://i.sstatic.net/qzo2c.png

I tried looking at the live code example (found at https://stackblitz.com/angular/vvxldjlmnna) to pinpoint what I might be doing wrong, but couldn't identify the problem.

To set up the in-memory web API, I first installed the necessary npm package by running

npm install angular-in-memory-web-api --save
. Checking the package.json file confirmed that the package was successfully downloaded as expected. The dependencies section now includes "angular-in-memory-web-api": "^0.6.1",.

In my app.module.ts, I imported the required modules in the following order:

@NgModule({
    FormsModule, 
    HttpClientModule,
    HttpClientInMemoryWebApiModule.forRoot(InMemoryDataService), 
    // I also tried:
    // HttpClientInMemoryWebApiModule.forRoot(
    //     InMemoryDataService, { dataEncapsulation: false }
    // ),
    AppRoutingModule

The dashboard display is implemented using the router-outlet and a router module defined like this:

const routes: Routes = [{ path: 'dashboard', component: DashboardComponent },
                        { path: '', redirectTo: '/dashboard', pathMatch: 'full' }
];
@NgModule({
    imports: [ RouterModule.forRoot(routes) ],
    exports: [ RouterModule ]
})

In the in-memory-data.service.ts file:

export class InMemoryDataService implements InMemoryDbService {
    createDb() {
        const DashboardReports = [
            { id: 1, date: new Date(2018, 8, 3, 0, 0, 0, 0), overtime: 0, project: 'W31226', superintendent: 'Toon', km: 105, status: 1 },
            { id: 2, date: new Date(2018, 8, 4, 0, 0, 0, 0), overtime: 1.75, project: 'W31226', superintendent: 'Toon', km: 105, status: 2 }
        ];

        return {DashboardReports}; // Pay close attention to the curly braces here
    }
}

// Overrides the genId method to ensure that a hero always has an id.
// If the DashboardReports array is empty,
// the method below returns the initial number (21).
// if the DashboardReports array is not empty, the method below returns the highest
// report id + 1.
genId(dashboardreport: DashboardReport[]): number {
    return dashboardreport.length > 0 ? Math.max(...dashboardreport.map(report => report.id)) + 1 : 21;
}

In the dashboard.service.ts file, I'm fetching data from the API using HttpClient. The DashboardService looks like this:

private dashboardDataUrl = 'api/dashboard';

constructor(private http: HttpClient) { }

/** GET Dashboard Reports from the server */
getDashboardReports (): Observable<DashboardReport[]> {
    return this.http.get<DashboardReport[]>(this.dashboardDataUrl);
}

In the dashboard component, I retrieve the data by calling the service:

ngOnInit() {
   this.getReports();
}
getReports(): void {
    this.dashboardService.getDashboardReports().subscribe(reports => this.dashboardReports = reports);
}

Lastly, here is the structure of the DashboardReport class:

export class DashboardReport{
    id: number;
    date: Date;
    overtime: number;
    project: string;
    superintendent: string;
    km: number;
    status: number;
}

Answer №1

Your issue lies in the way you structured the object returned in your createDb function. Essentially, you are returning this object:

{ DashboardReports }

Keep in mind that this is just a shortcut for:

{ DashboardReports: DashboardReports }

This setup results in configuring the URL as:

'api/DashboardReports'

This URL is not what you're aiming for. You actually want it to be:

'api/dashboard'

To achieve this, you need to adjust the structure of the object you return. Here's one approach to make it work in your specific scenario:

export class InMemoryDataService implements InMemoryDbService {
    createDb() {
        const DashboardReports = ...;

        return { dashboard: DashboardReports };
    }
}

You may have noticed in the tutorial you're following that the property name being used is heroes and the corresponding URL is api/heroes: the property name dictates the endpoint of the URL.

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 possible to integrate ngx-translate with database-supported translations?

I am managing a vast database (pouchDB) that stores translations, with each language having its own dedicated database. How can I leverage ngx-translate to easily access these translations directly from the database? ...

Guidelines for converting an array into checkboxes using React Native with TypeScript

As I embark on my React Native journey, I have chosen to use TypeScript in my project. Currently, I am faced with the challenge of mapping an array into a checkbox. Enclosed below is a snippet from my JSON file: { "stud_name": "Adam", "sex": "male" ...

A step-by-step guide on troubleshooting JavaScript/Typescript code in VSCode with Bun.sh

Recently, I delved into using Bun to execute typescript files without the need for compiling them to js. So far, my experience has been smooth sailing. However, when it came time for runtime debugging, I hit a roadblock as I couldn't find any informat ...

Can someone demonstrate the process of looping through an array of arrays in Angular using various methods?

I am working with an array in my TypeScript file that looks like this: let order : any[] = [ [{order_id:1,order_name:"car"},{order_id:2,order_name:"honda car"},{order_id:3,order_name:"bmw car"}], [{order_id:4,order_name:"honda city car"}], ...

What is the reasoning behind an empty input value being considered as true?

I am facing an issue with the following code that is supposed to execute oninput if the input matches the answer. However, when dealing with a multiplication problem that equals 0, deleting the answer from the previous calculation (leaving the input empt ...

Ways to transform an ISO string formatted date time into the following hour

I have a function that converts my date to RFC3339 format, but I want it to be converted to the upper time limit. Could someone please help me figure out how to convert it to the upper limit? const date = new Date(); // converting to RFC 3339 format ...

Dealing with the error message "The 'new' keyword requires a constructor signature when targeting a type that does not have one, resulting in an implicit 'any' type.ts(7009)"

Currently, I am in the process of migrating an outdated JavaScript library to TypeScript for integration into Vue 3. However, I encountered an error message that states: 'new' expression, whose target lacks a construct signature, implicitly has a ...

Issue with Pagination in Angular 7: Functioning Error

I am having trouble with my pagination setup. I am struggling to understand how to properly pass this.total = res.totalPage; from the Component to the Service so that it can count the pages correctly. Currently, it is only displaying one page as shown in t ...

Navigating Angular applications using IIS server

I am encountering an issue with my Angular 4 app and a .NET Web API on the same IIS server. The angular app is located in the "/wwwroot/angular/" folder, while the web API is in the "/wwwroot/api/" folder. When I make a request to the web API, it works fin ...

Creating anchor links with #id that function correctly in an Angular project can sometimes be challenging

My backend markdown compiler generates the HTML content, and I need Angular to retrieve data from the server, dynamically render the content, and display it. An example of the mock markdown content is: <h1 id="test1">Test 1<a href="#test1" title ...

Creating a FormArray with multiple dimensions in Angular 4: A step-by-step guide

For my dynamic form project, I am using the ng-formly npm tool to create a form with sections and tabs, all controlled by a single submit button. According to the library's documentation, I have defined an interface called TabType which specifies diff ...

Index error persists despite using the 'in' operator for verification

Is it possible to use a string as an object index? Although using keyof is the recommended approach due to its specificity, I am curious why using a string is not allowed even after confirming it is a valid index with the in operator. For example: if (fie ...

JS implement a secure retrieve function without relying on strings

When working with Lodash, one common function utilized is get, which allows for retrieval of nested properties in objects like this: _.get(object, 'a[0].b.c'); // => 3 _.get(object, ['a', '0', 'b', 'c' ...

Default interface value

I have defined an Interface as shown below: export interface IItem { name: string; isActive?: boolean; } The data structure is like this: const data: IItem[] = [ { name: 'item1', isActive: true }, { name: 'item2', ...

Using TypeScript to narrow down a type union based on the return types of functions

Why does Typescript struggle to differentiate a type union composed of return types from functions without explicitly declaring the return type on the function? In this scenario, when I don't specify the return values of the event creator functions, ...

Angular 2 issue: ControlValueAccessor failing to detect changes

I've followed a tutorial and implemented ControlValueAccessor in my component. However, it seems that the changes to the ngModel are not being detected within the component. Did I overlook something? import { Component, OnInit, forwardRef } from &apo ...

Typescript requires that the argument passed is undefined

Typescript: 2.4.1 I am exploring the creation of a helper function to produce redux action creators. Here is what I have: interface IAction<T extends string, P = undefined> { type: T; payload: P; } function createAction<T extends strin ...

Angular2 - Automatically redirect back to referring URL once user successfully logs in

My Angular application is running smoothly on version 2.1.0, with protected routes using router Guards and canActivate. Whenever I try to access a protected area like "localhost:8080/customers," I immediately get redirected to the login page as expected. ...

Having Trouble with Ionic 2's Loading Controller

In my attempt to utilize the recently added LoadingController in this scenario: let loading=this.load.create({ content: "Connexion au serveur Migal en cours..." }); loading.present(); this.http.get(this.urlCheckerForm.value.migalUrl+'/action/Mobi ...

Components with labeled elements are my specialty

Running Lighthouse on my local project has resulted in the following feedback: The form elements lack associated labels To address this issue, I have been using id="<input_id>" for inputs and adding for="<input_id>" to their corresponding l ...