Conditional compilation of Angular app

I am trying to simulate Angular Tour of Heroes using Webpack and work in both browser and Electron. I would like to conditionally create a HeroService class with direct REST requests to the browser and use IPC so that the main process is executed when using Electron. I'm still pretty new to Typescript, so I'm not sure if this event is possible. TARGET

is a config file variable that determines whether the webpack target should be web

or electron-renderer

. I can't seem to get awesome-typescript-loader

just conditionally execute let ipc = require('electron').ipcRenderer

. It works when I set a targetelectron-renderer

and can use it in Electron, but of course node integration is enabled, so I get demanding usage when I try to run it in a browser. I have tried the service as a class and an object but no luck. Here's an example.

import {Injectable} from '@angular/core';
import {Headers, Http} from '@angular/http';
import {Hero} from './hero';
import axios from 'axios';
import {DB_HOST, DB_PORT, API_URL, TARGET} from '../../config/';
const heroesUrl = `http://${DB_HOST}:${DB_PORT}/${API_URL}`;

type HeroServiceType = {
  getHeroes: () => Promise<Hero[]>,
  getHero: (id: number) => Promise<Hero>,
  delete: (id: number) => Promise<void>,
  create: (name: string) => Promise<Hero>,
  update: (hero: Hero) => Promise<Hero>
}

let ipc: typeof ipcRenderer;

let HeroService: HeroServiceType;

if (TARGET === 'web') {
  HeroService = {
    getHeroes: () => {
      return axios.get(heroesUrl)
      .then(response => response.data)
      .catch(err => handleError(err));
    },

    getHero: (id) => {
      return axios.get(`${heroesUrl}/${id}`)
      .then(response => response.data[0])
      .catch(err => handleError(err));
    },

    delete: (id) => {
      return axios.delete(`${heroesUrl}/${id}`)
      .then(() => null)
      .catch(err => handleError(err));
    },

    create: (name) => {
      return axios.post(
        heroesUrl,
        JSON.stringify({name}),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(response => response.data)
      .catch(err => handleError(err));
    },

    update: (hero) => {
      return axios.put(
        `${heroesUrl}/${hero.id}`,
        JSON.stringify(hero),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(() => hero)
      .catch(err => handleError(err));
    }
  };
}

else {
  let ipc = require('electron').ipcRenderer;

  const handleIPC = function(method: string, query: object): Promise<any> {
    ipc.send(method, query);
    return new Promise((resolve) => {
      ipc.once(method, (event, args) => {
        if (args.err) handleError(args.err);
        else if (args.data) resolve(args.data);
        else resolve();
      });
    });
  }

  HeroService = {
    getHeroes: function() {
      return handleIPC('getAll', {});
    },

    getHero: function(id) {
      return handleIPC('get', {id});
    },

    delete: function(id) {
      return handleIPC('delete', {id});
    },

    create: function(name) {
      return handleIPC('create', {name});
    },

    update: function(hero) {
      return handleIPC('update', {hero});
    }
  };
}

function handleError(error: any): Promise<any> {
  console.error('An error occurred', error);
  return Promise.reject(error.message || error);
}

export {HeroService, HeroServiceType};

      

I've tried several things. The current example is based on this post . Any help or suggestions for an alternative is greatly appreciated

Here it is like a class

import {Injectable} from '@angular/core';
import {Hero} from './hero';
import {TARGET} from '../../config';
import axios from 'axios';
import {ipcRenderer} from 'electron';

@Injectable()
export class HeroService {
  private heroesUrl = 'http://localhost:8081/api/heroes';

  getHeroes(): Promise<Hero[]> {
    if (TARGET === 'web') {
      return axios.get(this.heroesUrl)
      .then(response => response.data as Hero[])
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('getAll', {});
    }
  }

  getHero(id: number): Promise<Hero> {
    const url = `${this.heroesUrl}/${id}`;
    if (TARGET === 'web') {
      return axios.get(url)
      .then(response => response.data as Hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('get', {id});
    }
  }

  delete(id: number): Promise<void> {
    const url = `${this.heroesUrl}/${id}`;
    if (TARGET === 'web') {
      return axios.delete(url)
      .then(() => null)
      .catch(this.handleError);
    }
    else {
      this.handleIPC('delete', {id});
    }
  }

  create(name: string): Promise<any> {
    if (TARGET === 'web') {
      return axios.post(
        this.heroesUrl,
        JSON.stringify({name}),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(response => response.data as Hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('create', {name});
    }
  }

  update(hero: Hero): Promise<any> {
    const url = `${this.heroesUrl}/${hero.id}`;
    if (TARGET === 'web') {
      return axios.put(
        url,
        JSON.stringify(hero),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(() => hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('update', {hero});
    }
  }

  private handleIPC(method: string, query: object) {
    ipcRenderer.send(method, query);
    return new Promise((resolve) => {
      ipcRenderer.once(method, (event, args) => {
        if (args.err) this.handleError(args.err);
        else if (args.data) resolve(args.data);
        else resolve();
      });
    });
  }

  private handleError(error: any): Promise<any> {
    console.log('An error occured', error);
    return Promise.reject(error.message || error);
  }
}

      

+3


source to share





All Articles