Angular 2 define data models for multiple modules

A. Ziegler picture A. Ziegler · Oct 11, 2016 · Viewed 17.1k times · Source

I'm currently starting a new project with Angular 2.0 (release Version) and I want to define some global data models/schemas. As I understand it, Angular 2 has no default way of handling pure data classes like this:

export class TestModel {
  id: number;
  name: string;
  randomAttribute: number;
  author: string;
}

So my first question regarding best practices is: Should I define such classes when working with Angular 2?

For the design and concept of my whole application I think they are necessary but I'm not sure if I'm applying the wrong way of thinking here.

This data classes are sometimes needed in multiple modules (ngModule) so my second question is Where do I place them in my app? Currently I have the following structure:

/app
   /shared
      shared.module.ts
      test.model.ts
   /module1
      module1.module.ts
      foo.component.ts
      [...]
   /module2
      module2.module.ts
      bar.component.ts
      [...]
   app.module.ts
   [...]

My first thought was to include the instruction.model.ts in the shared.module and export it in every module that imports shared.module. That doesn't seem to work because the model is not a directive, pipe or module. Is there a way to export it anyway?

The simpler solution would be to just directly import the test.model.ts file and every other shared model in every module that needs it. But this seems clunky and not convenient for multiple models.

The third possible solution I thought of was to put all shared data models in a separate folder, bundle their export in a single file like the one below and import this file in every module that needs it.

Answer

A. Ziegler picture A. Ziegler · Nov 15, 2016

So, a month later I feel confident to answer this question myself and share the methods I used to resolve some of the problems described above. Most of them stemmed from a misunderstanding of the imports and exports in Typescript and Angular2 on my part or where just design decisions.

TL;DR: Yes, model classes can be helpful. Where to place them depends on your app and your preference but absolute paths for imports help. Everything else from the question doesn't really matter.

So my first question regarding best practices is: Should I define such classes when working with Angular 2?

I didn't work with AngularJS or any JavaScript framework before I adopted Angular2 but was used to the classic MVC pattern of PHP frameworks like Laravel. So this is where this question came from. The answer for me is yes, you should. Types are the big advantage in Typescript and defining data model classes or types helps to keep the app consistent, provides autocompletion in my IDE and the typescript compiler can notify me when I mess up. Furthermore this classes enforce consistency with my relational database in the backend. Still these model classes are optional and whether to use them is a design decision or even could be considered personal opinion.

my second question is Where do I place them in my app?

Like @Sam5487 pointed out in his answer this classes are just variables or objects, like nearly everything in JavaScript. So to import them you need to make them accessible globally and just use import {SomeDumbModel} from '../../../modelfolder' to import them somewhere in your app. Of course this works from any position in the app BUT this relative paths can get very long and clunky. So the real question should have been: Can I use absolute paths for imports?. And the answer is yes, at least with the angular-cli, webpack and typescript. I don't know the solution for SystemJS or other setups. I went with a /models folder at the root of my app which can be referenced my @models/ when importing anywhere.

My first thought was to include the instruction.model.ts in the shared.module and export it in every module that imports shared.module. That doesn't seem to work because the model is not a directive, pipe or module. Is there a way to export it anyway?

The Rest of the question is just based on my misunderstanding of imports and exports in Typescript and Angular2. All the stuff about modules and exporting it doesn't matter here and is important for completely different problems. Everything else should be answered by now.