0

I have an ionic 5.0.0 application I'm facing an issue in importing a component into another.

I have 2 different modules in my application which are ChatPageModule and HomePageModule. I want to include Chat template in Home template (like ng-include). So my home screen will be split in 2. Left side will render home template and right side will render chat template simultaneously.

To achieve this I created a SharedPageModule as follows.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { IonicModule } from '@ionic/angular';

import { ChatPage } from '../chat/chat.page';

const routes: Routes = [
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [ChatPage],
  exports: [ChatPage]
})

export class SharedPageModule {}

After that, I imported the SharePageModule into HomePageModule as follows

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { HomePage } from './home.page';
import { SharedPageModule } from '../shared/shared.module'


@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild([
      {
        path: '',
        component: HomePage
      }
    ]),
    SharedPageModule
  ],
  declarations: [HomePage]
})
export class HomePageModule {}

After I added the template selector of my Chat component into home template as follows.

<ion-header>
    <ion-toolbar>
        <ion-title text-center>HOME</ion-title>                
    </ion-toolbar>
</ion-header>

<ion-content  class="homepage-content no-scroll" >
<ion-row>
...
</ion-row>

<ion-row>
 ...
 </ion-row>

<ion-row>  
<app-chat></app-chat> <!-- Here it is -->
</ion-row>

</ion-content>

Up to this everything was fine. now the issue starts.

I want to call some methods written in ChatPage componennt from HomePage component. To do this I imported the Chat component in Home as follows.

import { Platform } from '@ionic/angular';
import { ChatPage } from '../chat/chat.page'


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
  
constructor(private chat: ChatPage) {}

  ngOnInit(): void {
   this.chat.getMessages();
  }
  
 }

But I got below error when i navigate to my home page.

core.js:15724 ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[HomePage -> ChatPage]: 
  StaticInjectorError(Platform: core)[HomePage -> ChatPage]: 
    NullInjectorError: No provider for ChatPage!
Error: StaticInjectorError(AppModule)[HomePage -> ChatPage]: 
  StaticInjectorError(Platform: core)[HomePage -> ChatPage]: 
    NullInjectorError: No provider for ChatPage!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:8896)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveToken (core.js:9141)
    at tryResolveToken (core.js:9085)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8982)
    at resolveNgModuleDep (core.js:21218)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:21907)
    at resolveNgModuleDep (core.js:21218)
    at resolvePromise (zone.js:831)
    at resolvePromise (zone.js:788)
    at zone.js:892
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)

3
  • if i am not wrong we have somthing called app.module.ts right ? can you import your chat or shared module in the app.module.ts file ? Just give it a try Commented Nov 14, 2019 at 8:50
  • Please create a stackblitz reproducing the issue Commented Nov 14, 2019 at 8:54
  • try declaring both - u have added only Home page in declarations: [HomePage], try declarations: [HomePage,ChatPage]. Hope it helps! Commented Nov 14, 2019 at 8:54

3 Answers 3

2

Besides everything, your error comes from the fact, that you didn't add a provider:

// home.page.ts

@Component({
  providers:  [ChatPage],
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss']
})
Sign up to request clarification or add additional context in comments.

Comments

0

You are injecting the ChatPage into the HomePage component, which is wrong. You don't need to inject anything. You just need to refer the instance of the ChatPage.

To do this, you can add a template variable in HTML, and use @ViewChild to read the component and call whatever method you want to call.

1 Comment

Hi Sachin Gupta Can you elaborate a little more with some sample codes?
0

This is not following the standards of Angular, to accomplish this you can use Events :

  1. Add the EventEmitter to your child component with the decorator @Output which will allow data to flow out of your component :
// chat-page.component.ts
// ...
@Output
onChat = new EventEmitter<string>();

/* Triggered when a user submit a message */
onSubmit(message: string) { onChat.emit(message) }

// ...
  1. In your parent component template, listen to this event ($event is the data of the event)
<app-chat (onChat)="aParentComponentMethod($event)"></app-chat>

Or in your situation it looks like you only want to get the messages when your component is initialized, doing this using a component is a wrong pattern, you have to use services :

// chat.service.ts
// ...
private messages: Message[] = [];

getMessages(): Message[] { return this.messages; }

addMessage(message: Message): void { this.messages.push(message); }
// ...

Then you can use it in your both components (Chat and Home) :

// home.component.ts
// ...
constructor(private chatService: ChatService) {}

ngOnInit() {
  this.chatService.getMessages();
}
// ...

If you really want to call a method of your child component you can still use @ViewChild

Links :

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.