A guide to building a versatile component using Ionic 3 and Angular 4

I decided to implement a reusable header for my app. Here's how I went about it:

First, I created the component (app-header):

app-header.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: 'app-header.html'
})
export class AppHeaderComponent {

  text: string;

  constructor() {
    console.log('Hello AppHeaderComponent Component');
    this.text = 'Hello World';
  }

}

This component has the following HTML structure:

app-header.html:

<div>
  {{text}}
</div>

Next, I added the AppHeaderComponent to the declarations array in my @NgModule:

...

import { AppHeaderComponent } from '../components/app-header/app-header';

@NgModule({
  declarations: [
    MyApp,
    TabsPage,
    AppHeaderComponent
  ],

...

Since I'm using TabsTemplate and want to include this header in every tab, I placed it in my feed.html file (one of the tabs):

<app-header></app-header>

<ion-content>

...

However, I encountered the following error:

Uncaught Error: Template parse errors: 'app-header' is not a known element: 1. If 'app-header' is an Angular component, then verify that it is part of this module. 2. If 'app-header' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. (" -->

[ERROR ->]

To address this issue, I modified the app-header.ts as follows:

import { Component, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: 'app-header.html'
})
@NgModule({
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppHeaderComponent {

  text: string;

  constructor() {
    console.log('Hello AppHeaderComponent Component');
    this.text = 'Hello World';
  }

}

Even after making this change, the error persisted.

Any suggestions on how to resolve this?

Update:

Since I am using Tabs, here's a snippet from my code:

tabs.ts:

import { Component } from '@angular/core';

import { FeedPage } from '../feed/feed';
import { AboutPage } from '../about/about';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {

  tabFeed = FeedPage;
  tabAbout= AboutPage;

  constructor() {

  }
}

And tabs.html:

<ion-tabs>
  <ion-tab [root]="tabFeed" tabIcon="paper"></ion-tab>
  <ion-tab [root]="tabAbout" tabIcon="search"></ion-tab>
</ion-tabs>

Each tab loads a page, like feed.html which was mentioned earlier.

For better organization, I have structured my code in the following way:

https://i.sstatic.net/KtvX5.png

Furthermore, the components.modules.ts includes:

import { NgModule } from '@angular/core';
import { AppHeaderComponent } from './app-header/app-header';
@NgModule({
    declarations: [AppHeaderComponent],
    imports: [],
    exports: [AppHeaderComponent]
})
export class ComponentsModule {}

Answer №1

To properly clean up your code, make sure to delete the reference in app.module.ts since this component is already declared in the ComponentsModule.

app.module.ts

@NgModule({
  declarations: [
    MyApp,
    TabsPage,
    //AppHeaderComponent <-- Delete this line
  ],

Next, ensure that you import the ComponentsModule in the module file associated with the page where it's needed.

my.module.ts

@NgModule({
  declarations: [
    MyPage,
  ],
  imports: [
    IonicPageModule.forChild(MyPage),
    ComponentsModule <-- Add this import statement here
  ],
})
export class MyPageModule { }

Answer №2

If you want to utilize Ionic wrappers like ion-grid, ion-row, etc., your ComponentsModule must be structured correctly.

components.module.ts

import {NgModule} from '@angular/core';
import {CreatePostComponent} from './create-post/create-post';
import {IonicModule} from "ionic-angular";

@NgModule({
    declarations: [
    CreatePostComponent,
  ],
    imports: [
    IonicModule, <== ensure to import IonicModule
  ],
    exports: [
    CreatePostComponent,
  ]
})
export class ComponentsModule {}

After setting up the ComponentsModule, make sure to include it in the imports array of any other component's module.ts file where you intend to use it. For instance, if you wish to use CreatePostComponent in your newsfeed page (ionic page).

newsfeed.module.ts

@NgModule({
  declarations: [
    NewsfeedPage,
  ],
  imports: [
    IonicPageModule.forChild(NewsfeedPage),
    ComponentsModule
  ],
})

Then, you can insert your CreatePostComponent selector (create-post in this example) within the newsfeed.html file.

<create-post></create-post>

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

Developing a typescript React component with a generic callback event handler function passed as a prop

I'm struggling with developing a callback event handler function that can be passed down as a prop to my component. My objective: Allow users to provide a custom callback function that: always accepts the same argument an event (not a react/dom even ...

Implement FieldResolver in TypeGraphQL for an array of objects

My current dilemma revolves around a specific issue related to the definition of my Cart type, which is structured as follows: @ObjectType() export class Cart { @Field(() => ID) id: string; @Field((_type) => String) ownerId: String ...

Remove the user along with all of their associated documents from Firestore

When a user wants to delete their account, I need to ensure that the 'documents' they created in Firebase are deleted as well. After some research online, I came across the following code snippet: deleteAccount() { const qry: firebase. ...

Retrieving the URL of a previous page in a Nest.js server

In our application, we utilize Angular 8 for the user interface and Nest Js server. One challenge we are facing is that when navigating to different pages within the application, the page URL includes a port number. While I am able to access this page UR ...

Creating a personalized aggregation function in a MySQL query

Presenting the data in tabular format: id | module_id | rating 1 | 421 | 3 2 | 421 | 5 3. | 5321 | 4 4 | 5321 | 5 5 | 5321 | 4 6 | 641 | 2 7 | ...

What are the best practices for presenting Motion JPEG binary data streams using Angular, Ionic, and JavaScript?

I am developing an application for a device that will receive a POST request and send back a binary data stream in the format of multipart/x-mixed-replace. My goal is to display this stream on a specific section of my app's homepage. After conducting ...

Angular and JavaScript Performing Slide-Up Animation

Currently, I am working on creating a menu using Angular and JavaScript. My goal is to have this menu toggle between showing and hiding when a button is clicked. If you would like to view the code that I have written so far, you can check out the demo her ...

Is there a way to configure Angular CLI to enable loading a favicon with a content hash for its filename?

I am looking to cache my website's favicon in the same way I cache css, js, and png files by setting an expires header far into the future. However, I am struggling to figure out how to achieve this. Most resources I come across suggest using a link i ...

"Troubleshooting the issue of Angular's select binding causing a disruption

The Angular version being used is 1.4.7. Within the model in question, there are two objects: 'systems', which is an array, and 'selectedSystem'. The desired outcome is for 'selectedSystem' to reference one of the objects wit ...

Issue with Dropdown menu in Navbar on Bootstrap 5 when using ng add installation technique

Here's my current setup: I'm currently using Angular 11.2.11 and Bootstrap 5 on a Windows system. The project I'm working on utilizes SCSS. The Issue at Hand: I've been following the codes provided in the bootstrap documentation (whi ...

Utilizing Angular 2 to retrieve and assign object properties provided by a service to a local variable within a

My video service: public getExercise(exerciseId): Observable<Exercise[]>{ let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers, withCredentials: t ...

Using an external variable within an internal function in TypeScript

I am facing a situation where I have a variable outside of a function that needs to be updated, but I am unable to access it using "this" as it is not reachable at that point in the code. export class GamesDetailPage { details : any = {}; type : St ...

The issue with the antd Input component's onChange event not updating state correctly when using a list fetched from an axios get request in a React

Recently delving into React, I've dedicated the past week to honing my skills. My current project involves creating a straightforward application featuring a 'product create' form alongside a product list equipped with a search bar (utilizin ...

Type verification not functioning properly in a standalone TypeScript function

I am trying to validate the type of a parameter in a separate function, but I keep getting this error: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable ...

Error message: Cypress Vue component test fails due to the inability to import the Ref type (export named 'Ref' is missing)

Recently, I created a Cypress component test for my Vue component by mounting it and verifying its existence. The component utilizes Vue's Ref type and is structured as a TypeScript component. However, during the test execution, Cypress encountered a ...

Extracting information from WordPress JSON API using Ionic

Using JSON API, I am able to fetch data from WordPress in Ionic. However, I am facing an issue where only 10 data points are being retrieved at a time from the WordPress JSON API. What is the best way to fetch the next set of 10 posts with an on-screen lo ...

Error encountered when importing a function in Typescript causes a compiler issue

When working with Typescript, I am utilizing the import function following the instructions provided at: https://github.com/Microsoft/TypeScript/issues/12933 My implementation looks like this: import("../myScriptToBeImported").then((module) => { ...

Receiving numerous inputs from a single text box using Angular

I'm facing an issue when trying to accept input as an array in Angular. Below is my code snippet: <input type="number" [(ngModel)]="valuesArray"> <button (click)="PerformAction()" > find</button> va ...

"Is there a way to dynamically remap an array only when there are changes

One of the challenges I am facing is with a component called Page, which contains two components - Editor and Preview. Page has an array called items. [ { value: 0, text: 'Item 1' }, ... ] This array items is passed ...

strictBindCallApply causing issues when working with generic parameters

Take a look at this slightly contrived code snippet: export function evaluate<T>(this: { value: T }) { return this.value; } class SomeClass { value: ''; constructor() { const result = evaluate.call(this); } } You might notice ...