angular-plugin-architecture icon indicating copy to clipboard operation
angular-plugin-architecture copied to clipboard

How can I use HttpClient in shared and plugin(s)

Open heino126 opened this issue 5 years ago • 7 comments

Hi,

I am trying to use the HttpClient from '@angular/common/http';. I want to use it in my Shared and in my Plugins. However I am not really figuring out what I am missing to make it work. I am getting this error.

image

What I currently have in my main app.

plugin-externals.ts

import * as core from '@angular/core';
import * as common from '@angular/common';
import * as forms from '@angular/forms';
import * as router from '@angular/router';
import * as HttpClient from '@angular/common/http';
import * as rxjs from 'rxjs';
import * as tslib from 'tslib';

// Setup to share libraries

export const PLUGIN_EXTERNALS_MAP = {
  'ng.core': core,
  'ng.common': common,
  'ng.forms': forms,
  'ng.router': router,
  'ng.HttpClient': HttpClient,
  rxjs,
  tslib
};

My shared.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';


import { SharedComponent } from './shared.component';
import { TabsComponent } from './tabs/tabs.component';
import { TabComponent } from './tabs/tab.component';
import { ButtonComponent } from './button/button.component';
import { HttpClientModule } from '@angular/common/http';


const sharedComponents = [SharedComponent, ButtonComponent, TabComponent, TabsComponent];

@NgModule({
  imports: [CommonModule, HttpClientModule],
  declarations: [...sharedComponents],
  exports: [...sharedComponents]
})
export class SharedModule { }

This is my config.service (that I want to have in my shared) where I want to use the HttpClient to get a config file (same file that I use in my main app) where I save some API stuff.


import { Injectable } from '@angular/core';
import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { environment } from './enviroment';

@Injectable({
    providedIn: 'any'
})
export class ConfigService {

    private config: any;

    constructor(private location: Location, private http: HttpClient) {
    }

    public load() {
        return this.getConfig();
    }

    get apiUrl(): string {
        return this.config.apiUrl;
    }

    private async getConfig(): Promise<any> {
        if (!this.config) {
            this.config = (await this.http.get(this.location.prepareExternalUrl(environment.configfile)).toPromise());
        }
        return Promise.resolve(this.config);
    }
}


My public-api.ts

/*
 * Public API Surface of shared
 */

// NOTE: NG9 require to export components exported by a module, also named exports is preferred if you were able to preserve aource-map of a plugin (shared lib could retain source-map) ;)
export { ButtonComponent } from './lib/button/button.component';
export { TabComponent } from './lib/tabs/tab.component';
export { TabsComponent } from './lib/tabs/tabs.component';
export { SharedComponent } from './lib/shared.component';
export { SharedModule } from './lib/shared.module';
export { ConfigService } from './lib/service/config.service'


And finally I want to create services in my Plugins that use the config.service from the shared to get the API URL that I need and make API calls from that service. Currently this is my Plugin3Service. Currently not using the HttpClient, but first solving one problem at the time.

import { Injectable } from '@angular/core';
import { ConfigService } from 'shared'

@Injectable({
    providedIn: 'root'
})

export class Plugin3Service {

    constructor(private config: ConfigService) {
    }
    configSutff() {

        console.log(this.config.apiUrl);
    }
} 

TLDR; How to add HttpClient in Shared and in Plugins?

*Edit: Added my public-api.ts

heino126 avatar May 20 '20 09:05 heino126

Hi, did you try to import the HttpClientModule in your host app-module and not in a plugin?

In a plugin, try not to import HttpClientModule again, simply inject the service in constructor. Injector should be able to get the instance from root injector. Unless interceptors need to be dynamic it's different design.

john-gouda avatar May 31 '20 02:05 john-gouda

@jfgouda Hi sorry for my late reply.

I have the HttpClientModule in only my host app-module and not in the plugins. However I did at it in my plugin-externals.ts Removing it from that file did not fix the issue.

heino126 avatar Jun 12 '20 06:06 heino126

@heino126 were you able to fix this issue?

iampervaze avatar Jul 29 '20 11:07 iampervaze

@iampervaze I am afraid not

heino126 avatar Jul 29 '20 11:07 heino126

@heino126 what I did was registered the HttpClientModule in the Shared Module and then injected the HttpClient Dependency in Plugin2 which seems to work but the bundle size increases because Plugin2 is dependent on Shared Module.

iampervaze avatar Jul 29 '20 13:07 iampervaze

@iampervaze Can you share an example of your solution please? I'm trying to solve same issue but no luck :(

EvilVir avatar Aug 29 '20 01:08 EvilVir

@EvilVir : Did you solve this issue. Im facing the same issue as you. @iampervaze : Can you help share your code

vodinhthien avatar Nov 08 '20 08:11 vodinhthien