Make sure to load the data in Angular before the component is rendered

My goal is to preload the data for locations before the component is rendered.

dashboard.html

{{ places[0]._id }} //testing purposes

dashboard.ts

import { Component, OnInit } from '@angular/core';
import { PlacesService } from 'src/app/services/places/places.service';
import { IPlace } from 'src/app/types/places';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent {
  places: IPlace[] = [];
  
  constructor(
    private placesService: PlacesService,
    private route: ActivatedRoute,
  ) {
    
  }
  ngOnInit(): void {
    this.route.data.subscribe((data) => {
      this.places = data['places'];
    });
  }

}

places.resolver.ts

import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  ResolveFn,
  RouterStateSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import { PlacesService } from '../services/places/places.service';

import { IPlace } from '../types/places';

@Injectable({
  providedIn: 'root',
})
export class PlacesResolver {
  constructor(private placesService: PlacesService) {}

  resolve: ResolveFn<IPlace[]> = (
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<IPlace[]> => {
    return this.placesService.getPlaces();
  };
}

places.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable, pipe } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
  providedIn: 'root',
})
export class PlacesService {
  constructor(private http: HttpClient) {}

  getPlaces(): Observable<any> {
    var requestUrl = `/api/places`;

    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
    });
    return this.http.get(requestUrl, {
      headers: headers,
    });
  }
}

app-routing.module.ts

import { NgModule } from '@angular/core';
import { ActivatedRouteSnapshot, RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { PlacesResolver } from './resolvers/places.resolver';
import { AuthGuard } from './_helpers/authGuard/auth.guard';

const routes: Routes = [
  { path: '', component: HomeComponent },
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
    resolve: {
      places: PlacesResolver,
    },
    data: { role: [] },
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

I have a button to navigate to /dashboard: navbar.html

<button
    label="Dashboard"
    (click)="dashboardClick()"
    *ngIf="
      (null | isLoggedIn | async) && (['admin', 'worker'] | hasRole | async)
    "
  >
    Dashboard
  </button>

navbar.ts

In this scenario, there are two different types of dashboards where the URL will be ''

dashboardClick() {
    this.url = this.lastVisitedService.getLastVisited()?.split('/')[2] || '';

    this.router.navigate(['/dashboard', this.url]);
  }

When clicking the dashboard button, the _id is not displayed initially, but console.log(result) returns the data. Upon page refresh, the data is successfully logged and displayed on the page. What could be causing this issue? Is there an alternative approach? Feel free to request the interceptor setup if needed.

Answer №1

Success! I managed to resolve the issue.

It's a bit of a mystery as to why or how it actually works, but when using this.router.navigate(['/dashboard', this.url]); it directs me to a route that is incorrect. To fix this, I made sure to remove the url from the navigate array if it is empty, so that it properly navigates to .../dashboard instead.

This is now my updated method for clicking the dashboard button:

dashboardClick() {
    this.url = this.lastVisitedService.getLastVisited()?.split('/')[2] || '';
    if (this.url) this.router.navigate(['/dashboard', this.url]);
    if (!this.url) this.router.navigate(['/dashboard']);
  }

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

Modify certain parameters in the current route using Angular 6 router

Within my Angular 6 setup, the URLs are structured as follows: /{language}/{app_section}/{object_id}/{view}?queryparams... All sections of the application utilize a language selector component, which is included in the template of a parent route to ensur ...

Tips for extracting a keyword or parameters from a URL

I'm in the process of creating my personal website and I am interested in extracting keywords or parameters from the URL. As an illustration, if I were to search for "Nike" on my website, the URL would transform into http://localhost:3000/searched/Nik ...

Ways to resolve a 404 error on a live Angular application being hosted by NGINX

I am encountering an issue with my deployed application on a server where every time I refresh a specific page, I receive a NGINX 404 error. The application is running within Docker. Below is the configuration file for NGINX. server { listen 80; locat ...

TypeScript setter failing to activate

Here is a snippet of code from a class called VibrationElement: export class VibrationElement { private _amplitude: number; get amplitude(): number { return this._amplitude; } set amplitude(amplitude: number) { console.lo ...

Cannot compile Angular 4 Material table: Encountering unexpected closing tag

Currently, I am working on an Angular 4 Project that involves using Material. The main task at hand is to implement a table from Angular Material. However, the issue I am facing is that the table does not compile as expected. Here's the HTML code sni ...

What are the solutions for resolving 'undefined' errors while working with TypeScript Interfaces?

When working with TypeScript in my Next.js project, I encountered the following error message: Type '{ banner: { id: number; bannerImageUrl: string; } | undefined; }' is not assignable to type 'IntrinsicAttributes & Banner'. Prope ...

Navigating the use of property annotations in Mapped Types with remapped keys

After exploring the concept of Key Remapping in TypeScript, as shown in this guide, I am wondering if there is a way to automatically inherit property annotations from the original Type? type Prefix<Type, str extends string> = { [Property in keyo ...

Angular app experiences a breakdown due to a JitCompiler issue

After being given the responsibility of enhancing a project, I diligently added new modules and components. However, upon running the application, it crashes. Uncaught Error: Component EnquiryComponent is not part of any NgModule or the module has not bee ...

Angular 12's BehaviorSubject should have been empty object array, but it unexpectedly returns undefined

Exploring different scenarios with a livesearch functionality: No user input (observable = undefined) No results found (observable = empty array) Results found (observable = non-empty array) The issue lies in how my behavior subject interprets an empty a ...

Having trouble with vscode compiling the typescript file?

Even though I diligently followed the tutorial provided by vscode on compiling typescript code, I encountered a problem. The configurations were set up as per the instructions in the tutorial, but when I tried to run the code without debugging, I received ...

React with Typescript allows us to refine the callback type depending on the presence of an optional boolean prop

In my project, there's a component <Selector /> that can optionally accept a parameter called isMulti: boolean. It also requires another parameter called onSelected, whose signature needs to change depending on the value of isMulti (whether it i ...

Can React Hooks API be used in TypeScript without using JSX?

After attempting to convert the JSX version of the React Hooks API demo into one without JSX, following the guidelines provided in react-without-jsx documentation, I ended up with the code below: import React, { useState } from 'react'; import R ...

What is the best way to add color to the "ngx-star-rating" component?

I've been experimenting with the ngx-star-rating plugin, and I've tested different approaches like fill and color, but nothing seems to be working! Can anyone provide suggestions on how to change the star rating color from yellow to a different c ...

What is the process for turning off minifying bundles when constructing an Angular application?

After developing an Angular project and implementing Server Side Rendering (SSR) using the angular-universal package, I have successfully served my project with SSR on port localhost:4000. Now, I am looking to debug it in a similar way as we do in the sour ...

"Enhancing Row Styles based on Conditions in Angular 2 using Prime

In my Angular2 application, I am using PrimeNG components and trying to dynamically color rows in a DataTable based on certain field values. However, I am facing challenges with implementing this feature. Below is a simplified version of my model: export ...

Unable to locate module 'fs'

Hey there, I'm encountering an issue where the simplest Typescript Node.js setup isn't working for me. The error message I'm getting is TS2307: Cannot find module 'fs'. You can check out the question on Stack Overflow here. I&apos ...

Retrieving information from a Kendo grid cell

I am working on a web application that utilizes Kendo Grid. How can I retrieve the values of the "Ticket No" from the selected checkboxes? https://i.stack.imgur.com/aPOje.png This is my code: var grid = $("#poGrid").data("kendoGrid"); grid.items().filte ...

What could be causing the getTotals() method to malfunction?

I have been working on a finance app that is designed to update the "income", "expenses", and "balance" tables at the top each time a new item is added by the user. However, the current code seems to be failing in updating these values correctly based on u ...

Steps for resetting the ng-multiselect-dropdown

Is it necessary to wrap the ng-multiselect-dropdown in a form in order to reset it? code - app.component.html <div> <p id = "node">Select a Root API Object - </p> <p style="width:50%"> <ng-multiselect-dropdown [placeho ...

Leverage a TypeScript property descriptor to substitute the accessors without compromising on composability

Is there a way to create a TypeScript property descriptor that can override accessors and still be easily composed with other functionality? ...