I would use a service, here's a shortened example from one of my apps:
import {Injectable} from '@angular/core';
import * as _ from 'lodash';
@Injectable({
providedIn: 'root' // Just do @Injectable() if you're not on Angular v6+
})
export class UtilsService {
findObjectIndex(list: any[], obj: any, key: string): number {
return _.findIndex(list, function(item) {
return obj[key] === item[key];
});
}
findObjectByQuery(list: any[], key: string, query: string): any {
return _.find(list, function(item) {
return item[key].toLowerCase() === query.toLowerCase();
});
}
}
Then you can inject this service into anything, which is really useful and you keep things DRY.
You would simply inject it like so:
import {UtilsService} from 'app/shared';
export MyComponent {
constructor(private utils: UtilsService) {
utils.findObjectIndex([], {}, 'id'); // just an example usage
}
}
EDIT:
As @aalielfeky's answer says you could use static functions.
However, I would personally avoid static functions because they are borderline impossible to test properly as well as giving you hell once the time comes where you need to inject something in the constructor that is going to be used in one of the functions. Since static functions can't use anything that's injected.
Don't make the same mistake as me because you will end up having to rewrite a lot of code.
EDIT 2:
You can also use another approach which is to have just normal functions. This can be a good idea if your functions doesn't require dependency injections, which is normally the case for simple helper functions. Simply create a file, say helpers.ts
(or one file per function if you have many functions) and do:
export function sum(a: number, b: number) {
return a + b;
}
or alternative syntax:
export sum(a: number, b: number) => {
return a + b;
}
Now you can simply import this with either of these import statements (depending on if you have all functions in one file or one file per function):
import { sum } from 'helpers';
import { sum } from 'helpers/sum';
A good thing about this approach is that it's easily tree shakeable and also makes it slightly easier to unit test compared to using a service since you don't need to add extra code to your tests in order to get the service to work.