Transforming Angular 4's folder structure for improved architecture simplicity

I am faced with the challenge of organizing files and folders within an Angular 4 project in a way that allows for easy reorganization. Currently, my approach looks like this:

├───core
│   │   core.module.ts
│   │   index.ts
│   │
│   ├───models
│   │   │   index.ts
│   │   │
│   │   ├───api
│   │   │       api-response-list.interface.ts
│   │   │       api-response.interface.ts
│   │   │       index.ts
│   │   │       page-search-params.interface.ts
│   │   │
│   │   └───auth
│   │           auth-token.interface.ts
│   │           index.ts
│   │           token-type.type.ts
│   │
│   └───services
│           api.service.ts
│           auth-token.service.ts
│           auth.service.ts
│           crud.service.ts
│           index.ts
│           local-storage.service.ts
│

In each logical folder container, I have an index.ts file that serves as an export point. This setup allows for seamless movement of files. For example, if I were to relocate services/api.service.ts to services/api-service/api.serivce.ts folder, I only need to update the reference in index.ts while other parts utilizing the service remain unchanged.

//core/models/api/index.ts
    export { APIResponse } from './api-response.interface';
    export { APIResponseList } from './api-response-list.interface';
    export { PageSearchParams } from './page-search-params.interface';

--

//core/models/auth/index.ts
    export { AuthToken } from './auth-token.interface';
    export { TokenType } from './token-type.type';

--

//core/models/index.ts
    export { AuthToken, TokenType } from './auth';
    export { APIResponseList, APIResponse, PageSearchParams } from './api';

--

//core/index.ts
    export { ApiService, CRUDService } from './services';
    export { CoreModule } from './core.module';
    export { AuthToken, TokenType, APIResponseList, APIResponse, PageSearchParams } from './models';

Due to limitations with the Angular compiler, I cannot use export * everywhere, necessitating the manual re-exporting of components. Is there a more efficient method than using typescript barrels for ensuring safe migrations? Any suggestions are welcome.

Answer №1

If you're in need of a solution, I propose considering one of these two methods (or even both simultaneously) based on your specific requirements.

Firstly, you could implement the index export pattern, where you create an index file for each folder that exports the files within that particular scope. This would involve starting from the deepest level and working your way up. For example, you might ultimately reference the models folder and access all the entities within it with just one line of code:

import { AuthToken, TokenType.... } from './models/index'; // You can simply refer to the folder rather than explicitly mentioning the index.

Another approach involves mapping paths using TypeScript, enabling you to utilize absolute paths. This means that if you ever need to relocate or rename folders, you'll only have to modify one location. To explore this option further, I recommend visiting the following link:

How to use paths in tsconfig.json

You may also find the documentation helpful at this link:

https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping

It's possible to combine both of these strategies for optimal results.

I trust that this information proves beneficial to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve a mapping of keys from a generic object structure in TypeScript

I am trying to extract the key map from an object, and although I have created a function for this purpose, TypeScript is not happy with it. How can I resolve this issue without using acc: any? const origin = { a: 1, b: 'string', c: () =&g ...

Guide to utilizing Sheet Modal in Ionic 5

In the documentation for Ionic version %, there is a showcase of the sheet modal in mobile view but the code examples do not include it. If you want to learn how to use the Sheet Modal feature, you can check out the source code under the Mobile View sectio ...

Utilizing either Maps or Objects in Typescript

I'm in the process of developing a simple Pizza Ordering App. The concept is, you select a pizza from a list and it's added to a summary that groups all the selections together. Here's how I want it to appear: Pizza Margarita 2x Pizza Sala ...

Submitting the object in the correct format for the Firebase database

My goal is to structure the Firebase database in the following way: "thumbnails": { "72": "http://url.to.72px.thumbnail", "144": "http://url.to.144px.thumbnail" } However, I am struggling to correctly set the keys '72' and '144&apos ...

Ways to customize the appearance of Angular material elements one by one?

I have a component that contains two Angular Material form components: <!-- First input --> <mat-form-field> <mat-label>Password</mat-label> <input matInput type="text"> </mat-form-field> <br&g ...

Creating a Text Typer ReactJS component that functions properly regardless of whether or not it is used within StrictMode is no

My goal is to develop a custom Text Typer component that displays text character by character every 100ms. While it works perfectly fine in production, I encounter issues when testing it in the development environment. Despite trying various solutions, tw ...

Identifying the state type within the scope of TypeScript

For my project involving BMI calculation, I want to store the results in an array within a state and keep them locally. export type BmiContextState = { weight: number | undefined; height:number | undefined; open:boolean|undefined; alert:boo ...

Is it possible to create an observable with RXJS that emits only when the number of items currently emitted by the source observables matches?

I am dealing with two observables, obs1 and obs2, that continuously emit items without completing. I anticipate that both of them will emit the same number of items over time, but I cannot predict which one will emit first. I am in need of an observable th ...

Utilize rxjs to effectively handle API data responses and efficiently manage the state of your application within Angular 10

I'm currently exploring the most efficient method for storing and updating data from an API, as well as sharing that data among sibling components. Here's my initial attempt: Storing the Observable export class MyExampleService { private data ...

Tips for ensuring old logs do not display on Heroku Logs

I'm puzzled as to why my heroku logs command keeps showing old logs. Attempting to resolve this issue, I tried: heroku drains heroku logs However, the logs still display outdated information: app[api]: Release v1 created by user <a href="/cdn-c ...

Tips on sorting an array within a map function

During the iteration process, I am facing a challenge where I need to modify certain values based on specific conditions. Here is the current loop setup: response.result.forEach(item => { this.tableModel.push( new F ...

Encountering a cloning error while using React Typescript and React Router DOM when calling props.history.push

When using props.history.push without passing state, everything works perfectly fine. However, when trying to pass data with state, an error occurs. The error message reads: DOMException: Failed to execute 'pushState' on 'History': func ...

Setting a default value for NULL property in TypeScript

Trying to establish a default value for all NULL objects has been quite the challenge. The current code looks like this: private setDisplayAmount(summaries: summary[]): void { summaries.map(t => { // performing some operations, and then... ...

Angular 4 RXJS Observable .interval() Fails to Execute in the Background

I have implemented a basic timer observable in my application that works fine. However, I noticed that when the tab is not active, the timer stops until I switch back to it. public timer = Observable .interval(100) Is there a way to keep the observable ...

Tips on refining API response using Angular 2's HTTP module

This is the data I received from my transactions API: [{ "id": 1, "description": "Sandwich", "date": "2017-09-01", "category": "Take away", "tags": ["Holidays"], "amount": -2 },{ "id": 2, "description": "Wage", "date": "2017-08- ...

Block users from printing in text input with Angular

I need to restrict users from entering text into a specific input field, even though they can click on it and select the value. Using the disabled attribute is not an option because it triggers another event when clicked. I also want users to have the ab ...

After transitioning from deprecated TSlint to ESLint, which style guide is most similar to TSLint in the ESLint ecosystem?

QUERY - Can anyone recommend the closest ESLint style guide to TSLint for an Angular project in VSCode? I'm looking for a out-of-the-box solution that doesn't require me to tweak too many rules in .eslintrc.json file. I initially set up my style ...

Measuring the height of an element within its parent component using Angular 4

Check out my demo here I've created a basic parent component along with a child component. Is there a way to retrieve the height of the parent div from within the child component? import { Component, Input, ElementRef, OnInit, ViewChild } from &apo ...

Navigating the waters of importing npm modules with typescript, gulp, and browserify is a skill

I'm facing challenges with performing some fundamental tasks such as importing packages that I installed using NPM. Despite conducting extensive research online and following various tutorials, I have been unable to achieve success. Here is my current ...

Ways to adjust the size of a Primeng autocomplete with multiple selections?

I'm new to Angular and I'm attempting to adjust the width of a primeng auto complete component in order to fill the column of a table. I've already experimented with using style="width: 100%" but that approach hasn't yielded any result ...