Utilizing a navigation menu to display various Strapi Collection pages within a single Angular Component

I have set up a collection in Strapi called Pages and I am looking to display them in the same component using my Navigation Bar Component. However, I am unsure of how to achieve this.

Currently, all the data from the Collection is being displayed like this: https://i.sstatic.net/hTh21.png

My question is, how can I render a specific Page using the navigation bar? For example, when I click on "Ratenrechner," only the content related to "Ratenrechner" should be shown.

The reason for rendering in the same component is because all these pages share the same structure.

I will provide my components and services code below. Please let me know if you need more information or code to assist with this issue. I will try to keep it concise and include all necessary details.

app.routing.module.ts

const routes: Routes = [
  {
    path: '',
    redirectTo: 'page',
    pathMatch: 'full'
  },
  {
    path: 'page',
    component: PageComponent,
  }
]; 

page.service.ts

export class PageService {

  constructor(private http: HttpClient) { }

  getAllPages(): Observable<Page> {
    return this.http.get<Page>(`${environment.apiUrl}/pages`).pipe(map(res => res));
  }

  getPage(pageID: any):Observable<Page> {
    return this.http.get<Page>(`${environment.apiUrl}/pages/${pageID}`).pipe(map(res => res));
  }

page.component.ts

export class PageComponent implements OnInit {
  pages?: Page;

  constructor(private pageSvc: PageService, private route: ActivatedRoute) {
  }

  ngOnInit(): void {
  this.getPages();
  }

  getPages() {
    this.pageSvc.getAllPages().subscribe(res => {
      this.pages = res;
    })
  }
}

page.component.html

<div *ngIf="pages">
  <div *ngFor="let pageData of pages.data">
    <h1>{{pageData.id}} - {{pageData.attributes.title}}</h1>
  </div>
</div>

My navigation bar has also been created with Strapi as a Content Type containing a Collection for the dropdown menu and links component;

navigation-bar.service

export class NavigationBarService {

  constructor(private http: HttpClient) {
  }
  // function to get all data response from top-left-menu in strapi
  getAllNavbarComponents(): Observable<Navbar> {
    return this.http.get<Navbar>(`${environment.apiUrl}/top-left-menu?[populate]=*`).pipe(map(res => res));
  }
}

navigation-bar-dropdown.service.ts

export class NavigationBarDropdownService {

  constructor(private http: HttpClient) { }

  getAllDropdownComponents(): Observable<Dropdown> {
    return this.http.get<Dropdown>(`${environment.apiUrl}/sections?[populate]=*`).pipe(map(res => res));
  }

}

navigation-bar.component.ts

export class NavigationBarComponent implements OnInit {

  components?: Navbar;
  dropdownComponents?: Dropdown;

  constructor(private navbarSvc: NavigationBarService, private dropdownSvc: NavigationBarDropdownService) {
  }

  ngOnInit(): void {
    this.getNavbarComponents();
    this.getDropdownComponents();
  }

  getNavbarComponents() {
    this.navbarSvc.getAllNavbarComponents().subscribe(res => {
      this.components = res;
    })
  }

  getDropdownComponents() {
    this.dropdownSvc.getAllDropdownComponents().subscribe(res => {
      this.dropdownComponents = res;
    })
  }

}

navigation-bar.component.html

<ng-container *ngIf="components">

  <nav class="navbar navbar-expand-lg bg-light">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">Navbar</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
              aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse " id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown"
               aria-expanded="false">
              Ratgeber
            </a>
            <ng-container *ngIf="dropdownComponents">
              <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
                <div class="row row-cols-auto">

                  <div class="col" *ngFor="let dropdownComponent of dropdownComponents.data">
                    <!--            SECTION LABEL-->
                    <li
                      class="text-center my-2 fw-bold"
                    >
                      {{dropdownComponent.attributes.label}}
                    </li>
                    <!--            SECTION LINKS-->
                    <li
                      *ngFor="let link of dropdownComponent.attributes.links"
                    >
                      <a href="{{link.url}}">{{link.label}}</a>
                    </li>
                    <li>
                      <hr class="dropdown-divider">
                    </li>
                  </div>
                </div>
              </ul>
            </ng-container>
          </li>
          <li class="nav-item" *ngFor="let sectionComponent  of components.data.attributes.body">
                <a class="nav-link" href="{{sectionComponent.url}}">{{sectionComponent.label}}</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
</ng-container>

Answer №1

Sharing my solution to a problem in case others encounter the same issue in the future. It may not be the most elegant way, but it gets the job done for now.

A helpful video that guided me: https://www.youtube.com/watch?v=JT3s9HQxc1c

If anyone has a better solution, please feel free to share.

I utilized ActivatedRoute to retrieve the current URL and created a function to fetch a specific page by ID, passing the current route's ID as a parameter to the function.

page.component.ts

export class PageComponent implements OnInit {
  page?: Page;
  pageID?:  {id: number;};
  constructor(private pageSvc: PageService,private route: ActivatedRoute) {
  }

  ngOnInit(): void {
  this.pageID =  {
    id: this.route.snapshot.params['id']
  }
    this.getSpecificPage(this.pageID.id);
    // this.getPages();
  }

  // getPages() {
  //   this.pageSvc.getAllPages().subscribe(res => {
  //     this.pages = res;
  //   })
  // }

  getSpecificPage(id: any) {
    return this.pageSvc.getPage(id).subscribe( res => {
      this.page = res;
      console.log(this.page)
    })
  }
}


app.routing.module.ts

const routes: Routes = [
  {
    path: '',
    redirectTo: 'pages',
    pathMatch: 'full'
  },
  {
    path: 'pages/:id',
    component: PageComponent,
  }
];


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

In Typescript, ambient warnings require all keys in a type union to be included when defining method parameter types

Check out this StackBlitz Example Issue: How can I have Foo without Bar, or both, but still give an error for anything else? The TypeScript warning is causing confusion... https://i.stack.imgur.com/klMdW.png index.ts https://i.stack.imgur.com/VqpHU.p ...

What steps can I take to avoid an invalid operation on a potentially null reference in typescript?

Take a look at this scenario where the variable a can potentially be null, and is explicitly defined as such. Even when strict null checks are enabled, TypeScript does not flag a possible issue in this situation - let a: string | null = "hello" function ...

What is the best way to write a function in typescript that verifies whether the argument extends a type argument and then returns the argument?

I need to create a function that checks if the argument's type extends a specific type variable and then returns the argument. Something like this: declare function checkType<T, X extends T>(argument: X): X However, TypeScript gives an error wh ...

An issue has occurred with error code TS2688: The type definition file for 'jquery' cannot be located. [Angular Application] --

I am currently working on developing an Angular web application with a specific theme that requires the inclusion of CSS and JS files. Majority of the JS files needed are jquery plugins, so I made sure to install them using the following commands: npm i j ...

Having trouble retrieving data from mobx store in Ionic3

I am attempting to retrieve a value from the @computed getCategories() function, but every time I try to call this function, I encounter the following error: Cannot invoke an expression whose type lacks a call signature. Type 'any[]' has no comp ...

Problem with MongoDB - increasing number of connections

I have encountered an issue with my current approach to connecting to MongoDB. The method I am using is outlined below: import { Db, MongoClient } from "mongodb"; let cachedConnection: { client: MongoClient; db: Db } | null = null; export asyn ...

Implementing basic authentication and Cross-Origin Resource Sharing (CORS) in

I am currently attempting to make a simple HTTP API call using Angular to a standard API with Basic HTTP Authentication. However, I am encountering an issue where the browser is blocking the request with a "Cross-Origin Request Blocked" error message, citi ...

Angular2 Animation Transitions not triggering consistently for all events

Initially, take a look at this Plunkr I derived this from an example of page transition animation In essence, I am in need of setting custom states as I have varied animations for distinct actions within the site (e.g., initial load versus in-app page tr ...

An error callback is triggered when the HttpClient delete function encounters an issue, despite receiving a successful

My attempt to remove a basic student object using its ID is functioning correctly. However, instead of displaying the success message, it appears as an error message. Java backend code -> Controller code: @DeleteMapping("/student/{$id}") ...

Do you find this unattractive? What are some ways to improve this unsightly JavaScript statement?

This code seems messy, how can I better structure this switch statement? function renderDataTypeIcon(dataType: string) { let iconName; switch (dataType) { case "STRING": //TODO - ENUM iconName = "text"; break; ...

Struggling to implement the Pick utility type alongside the React useState hook

Can anyone explain why I am unable to utilize the Pick utility type in order to select a property from my interface and apply it to type my component's state? This is what my interface looks like: export interface IBooking { ... propertyId: strin ...

Oops, it seems like there was an issue with NextJS 13 Error. The createContext functionality can only be used in Client Components. To resolve this, simply add the "use client" directive at the

**Issue: The error states that createContext only works in Client Components and suggests adding the "use client" directive at the top of the file to resolve it. Can you explain why this error is occurring? // layout.tsx import Layout from "./componen ...

Accurate function calls with multiple parameters in TypeScript

As a beginner in TypeScript and currently exploring its integration with AngularJS, I am facing a particular issue where the compiler is not detecting an error. In Angular, a resource provider typically includes a get() method that returns an instance of ...

Issues with CORS functionality in Angular and NodeJS application causing disruptions

I am encountering issues with my Angular application that is Dockerized. When loading the application on Edge or Firefox, all the REST API requests needed to populate the homepage are not reaching the application. However, when I load the same page on Chro ...

Angular application integration with three.js OrthographicTrackballControls

Has anyone successfully integrated the OrthographicTrackballControls from three.js with Angular 4? I attempted to do so by running: npm install --save three-orthographic-trackball-controls Then in my component: import { OrthographicTrackballControls } f ...

Easy pagination for angular's in-memory-web-api

Looking for help to implement pagination in Angular-in-memory-web-api. Currently, I have the following setup: import { InMemoryDbService } from 'angular-in-memory-web-api'; export class InMemoryDataService implements InMemoryDbService { ...

Issue with data propagation in Angular 2 RC5 when using ngStyle in parent component

Here is a basic Angular 2 application setup I am working with: import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Test</h1> <test-component [Height] = "30 ...

Manually close the AntD Menu without using any shortcuts

I'm facing a unique situation with my table implemented using antd. Each row has a dropdown menu that opens a modal upon clicking. To ensure the dropdown menu doesn't trigger the row click event, I used stopPropagation on the menu item click. Eve ...

Struggling to accurately capture the values from checkboxes and dropdown selections to ensure the correct data is displayed. Assistance is needed in this

I am facing challenges in retrieving the accurate data for display from Mat-Select and Mat-Checkbox components. My goal is to capture the selected values from users and perform if-else statements to validate conditions, displaying the correct data view if ...

Mapping through multiple items in a loop using Javascript

Typescript also functions Consider an array structured like this const elementList = ['one', 'two', 'three', 'four', 'five'] Now, suppose I want to generate components that appear as follows <div&g ...