Home > other >  Error in Angular with shared Module: generates "appears in XXX.module but itself has errors&quo
Error in Angular with shared Module: generates "appears in XXX.module but itself has errors&quo

Time:02-26

Ionic v6 project with Angular. I have made several directives that I need to use in several pages. I have created a shared module:

import { MediaPage } from './../directivas/media/media.page';
import { TformPage } from './../directivas/tform/tform.page';
import { ViewformPage } from './../directivas/viewform/viewform.page';
import { TristatePage } from './../directivas/tristate/tristate.page';
import { IonicModule } from '@ionic/angular';
import { BtitleDirective } from './../directivas/btitle.directive';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

    @NgModule({
      declarations: [
          BtitleDirective,
          TristatePage,
          ViewformPage,
          TformPage,
          MediaPage
      ],
      imports: [
      ],
      exports:[
          CommonModule,
          IonicModule,
    
          BtitleDirective,
          TristatePage,
          ViewformPage,
          TformPage,
          MediaPage
      ]
    
    })
    export class SharedModule { }

I have the following error on each module that uses SharedModule:

SharedModule Appears in the NgModule.imports of HomePageModule, but itself has errors

These errors appear in VSCode and with ionic build, but with ionic serve everything is working well,

Any ideas?

CodePudding user response:

I have found a part of the problem. I have a component directive called TriState, showing 3 buttons. This is tristate.module.ts:

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

import { TristatePageRoutingModule } from './tristate-routing.module';

import { TristatePage } from './tristate.page';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    TristatePageRoutingModule
  ],
  declarations: [TristatePage],
})
export class TristatePageModule {}

tristate.page.ts

import { UtilService } from './../../services/util.service';
import { Component, Input, Output, EventEmitter, forwardRef, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-tristate',
  templateUrl: './tristate.page.html',
  styleUrls: ['./tristate.page.scss'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => TristatePage),
    multi: true
}]

})
export class TristatePage implements ControlValueAccessor,OnInit {
  @Input() label: string = '';
  @Input() readonly: boolean;

  @Output() onchange: EventEmitter<string> = new EventEmitter<string>();

  value: string ;

  onChange: (_: any) => void = (_: any) => {}; //Invoked when the model has been changed
  onTouched: () => void = () => {}; // Invoked when the model has been touched

  constructor(
      public utilS: UtilService
  ) {}
  public ngOnInit(){
    console.log('oninit tri',this.value);
    this.value='';
  }

  public setvalue() {
     //console.log($event,this.value);
    if(this.readonly) return;
    //this.value = this.options[p].value;
    this.updateChanges();
    if(this.onchange)
        this.onchange.emit(this.value);
  }

  /**
   * Method that is invoked on an update of a model.
   */
  updateChanges() {
    if(!this.value) return;
    console.log('updchange',this.value);
    this.onChange(this.value);
  }


  ///////////////
  // OVERRIDES //
  ///////////////

  /**
   * Writes a new item to the element.
   * @param value the value
   */
  writeValue(value: string): void {
    console.log('write ',this.value);
    if(value) 
        this.value = value;
    this.updateChanges();
  }

  /**
   * Registers a callback function that should be called when the control's value changes in the UI.
   * @param fn
   */
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  /**
   * Registers a callback function that should be called when the control receives a blur event.
   * @param fn
   */
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}

And tristate.page.html:

<div >
    <div >
        <h3>{{label}}</h3>
        <ion-segment (click)="setvalue()" [(ngModel)]="value" >
            <ion-segment-button value="S" style="--background-checked:green;" >
                Sí
              <ion-icon name="{{utilS.conficons.S}}"></ion-icon>
            </ion-segment-button>

            <ion-segment-button value="P" style="--background-checked:orange">
              <ion-icon name="{{utilS.conficons.P}}"></ion-icon>
              N/C
            </ion-segment-button>
            
            <ion-segment-button value="N" style="--background-checked:red;">
                No
                <ion-icon name="{{utilS.conficons.N}}"></ion-icon>
           </ion-segment-button>
 
          </ion-segment>
    </div>
</div>

If I remove TristatePage from module declarations, above errors "SharedModule Appears in the NgModule.imports of...", disappear, but I have a new one in template:

Can't bind to 'ngModel' since it isn't a known property of 'ion-segment'.

I don't understand what happens..:(

CodePudding user response:

It's as the error says: ngModel isn't a known property of ion-segment. link to ionic docs

The only way I can see to get the selected segment is to use the 'ionChange' event as documented in the ionic docs.

In your html:

<ion-segment (ionChange)="segmentChanged($event)">

In your typescript:

segmentChanged(ev: any) {
   console.log('Segment changed', ev);
 }
  • Related