anna.len
anna.len

Reputation: 91

How do I overwrite an existing component in angular?

I am trying to overwrite an existing component in angular.

My original component is:

@Component({
  selector: 'app-orginal',
  templateUrl: './orginal.component.html',
  styleUrls: ['./orginal.component.css']
})
export class OrginalComponent implements OnInit {
}

in the app.component.html I use the original component like that:

<app-orginal></app-orginal>

What you would like to do is overwrite the original component with the mock component.

This is my mock component:

@Component({
  selector: 'app-mock-of-orginal',
  templateUrl: './mock-of-orginal.component.html',
  styleUrls: ['./mock-of-orginal.component.css']
})
export class MockOfOrginalComponent implements OnInit {
}

Related to this answer https://stackoverflow.com/a/49327712/7717382 I tried to use this solution in my app.module.ts:

@NgModule({
    declarations: [
        AppComponent,
        OrginalComponent,
        MockOfOrginalComponent
    ],
    imports: [
        BrowserModule,
        HttpClientModule,
        RouterModule.forRoot([
            {path: 'app-mock-of-orginal', component: MockOfOrginalComponent},
            {path: 'app-orginal', redirectTo: 'app-mock-of-orginal', pathMatch: 'full'},
        ]),
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {
}

But it does not work. What did I do wrong?

Here is my git-hub project: https://github.com/annalen/overwrite-component

Thanks for the help.

Upvotes: 8

Views: 15702

Answers (1)

Reactgular
Reactgular

Reputation: 54771

To replace a component with an alternative it has to replace the declaration of the original. You're example is declaring both components at the same time, but with different selectors. The key is to use the same selector, but only declare one.

@Component({selector: 'app-original'})
export class MockAppComponent {
      // this will replace AppComponent
}

@Component({selector: 'app-original'})
export class AppComponent {
}

// You could use a value from environment.ts
// if you need to toggle this at compile time.
const mockFlag = true;

@NgModule({
    declarations: [
       mockFlag ? MockAppComponent : AppComponent,
    ],
    imports: [
        BrowserModule,
        HttpClientModule,
        RouterModule.forRoot([]),
    ],
    providers: [],
    bootstrap: [mockFlag ? MockAppComponent : AppComponent]
})
export class AppModule {
}

Angular will not allow you to declare two components that share the same selector, but you have to use that selector if you don't want to change your templates.

I'm not sure why you want to do this. Maybe this isn't want you need.

Upvotes: 4

Related Questions