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

ngFor failing to properly update when new data is pushed

I am currently working on creating an array of reactive forms in Angular. Here is what I have set up: typesForms: FormGroup[] = []; In my HTML, I loop through this array like so: <form *ngFor="let type of typesForms; let i = index" [formGroup]="types ...

Testing the functionality of NgRx effect through unit testing

Looking to unit test a functional effect found in this code snippet export const loadUsers = createEffect( (actions$ = inject(Actions), usersService = inject(UsersService)) => { return actions$.pipe( ofType(userActions.getUser), exhaus ...

The "pointer" cursor style is simply not functioning in any way

Here is the angular template code I am working with: <!-- Modal --> <ng-template #levelsmodal let-c="close" let-d="dismiss"> <div class="modal-header"> Select the levels you want to show in the table and chart ...

Creating an Ionic v4 alert box that redirects users to different pages

I am facing an issue with my ion-alert component where I have set up a message with two options, "To Myself" and "To Someone", that should act like buttons and route to different pages in the application. However, using (click) events or [routerLink] on th ...

The argument provided needs to be a function, but instead, an object instance was received, not the original argument as expected

I originally had the following code: const util = require('util'); const exec = util.promisify(require('child_process').exec); But then I tried to refactor it like this: import * as exec from 'child_process'; const execPromis ...

TypeScript perplexed Babel with its unfamiliar syntax and could not compile it

Encountered a problem while attempting to compile typescript. It appears that babel was unable to comprehend the "?." syntax on the line node.current?.contains(event.target) export function useOnClickOutside(node: any, handler: any) { const handlerRef = ...

The Excel Match function is experiencing issues when used in conjunction with the MS-Graph API

Recently, I've encountered an issue with sending a match-function post request to an Excel workbook using the MS-Graph API. Instead of receiving the value of the first column that contains the lookup value, I'm getting the value from the second c ...

Troubleshooting a child process created by electron in Visual Studio Code

I am currently in the process of developing an electron application using typescript and webpack. I have encountered a specific debugging issue with vscode that I would like some assistance with: Context: The main process initiates a child process by call ...

How can I utilize a filter or pipe to populate product categories onto screens within Ionic 2?

I am considering creating an Ionic 2 app with 6 pages, but I'm unsure whether to utilize a Pipe or a Filter for the individual category pages and how to implement the necessary code. Each category page should be able to display products from the "app ...

How to Toggle Visibility of Angular2 Material Drop Down Menu?

My Code <mat-form-field class="button-spacing"> <mat-select placeholder="select" [(ngModel)]="dropDownOne"> <mat-option *ngFor="let first of test1" [value]="first"> {{ first }} </mat-option> </mat-select> </mat-fo ...

The Firebase storage percentChanges() method is throwing a NaN error

I want to create a Firebase storage service using an Angular client to handle user profile image uploads. This service should return two observables: uploadProgress$ and downloadUrl$. The uploadProgress$ observable will store the value from percentChanges ...

Is there a way to recursively convert property types from one to another in an object that contains optional properties?

The scenario: I am currently working with MongoDB and a REST API that communicates using JSON. MongoDB uses objects instead of identifiers for documents, but when these objects are stringified (such as in a response body), they get converted into strings. ...

Troubleshooting: Issues with accessing Angular/Typescript Class Getter property

I have a class defined as follows: export class Story { id: number; title: string; storyText: string; utcDate: string; get displayDate(): string { const today = new Date(); const postDate = new Date(this.utcDate); ...

Eliminate any repeated elements in the array by utilizing TypeScript

Hey, I'm trying to figure out how to remove duplicate entries from an array where the UserId values are the same, and keep only one of each unique entry. Can anyone help me with this? For example: a=[ {userId:1,name:''}, {userId:2,name:&apo ...

The Child/Parent arguments in Typescript methods cannot be assigned

Why is this not working in TypeScript? class Parent { id: string = '' } class Child extends Parent{ name: string = '' } const fails: (created: Parent) => void = (created: Child) => { return }; const failsToo: ({ create ...

Retrieving header information in Angular 6

I am currently working on an example that I found on this website, but I seem to be facing an error that I can't figure out. Even after carefully reviewing my code, I'm still unable to pinpoint the mistake. Specifically, when I use "response => ...

Transforming an ordinary JavaScript object into a class instance

As I was delving into Angular's documentation on "Interacting with backend services using HTTP", I came across the following statement in the "Requesting a typed response" section: ...because the response is a plain object that cannot be automatical ...

Is it possible to have a button within a table that, when clicked, opens a card overlaying the entire table?

I'm having an issue with a table and card setup. When I click the button in the table, the card that appears only covers part of the table. I want it to cover the entire table area based on the content inside the card. How can I make this happen? I&a ...

NG8003 error: ExportAs 'ngForm' directive not found in the system

I encountered an issue with my first Angular 11 project: No directive found with exportAs 'ngForm'. Despite importing FormsModule and ReactiveFormsModule in app.module.ts, the error persists. Here is the code snippet: This is from product.compon ...

The art of neatly bundling a Typescript external module at the highest level

I'm currently working on a TypeScript NPM package, where I have organized all the classes and interfaces. However, upon review, it seems that my approach is repetitive and not very clean, especially with the empty class and interface extensions. I am ...