This article was first published on Medium.
For those who do not know yet, FrintJS is an environment agnostic framework for building scalable reactive applications supporting both React and Vue.js.
Since the v1 release in early 2017, the core of the FrintJS framework has been mostly responsible for handling dependencies in your Apps. While other packages are mostly built around the core frint package’s API.
Providers
We have a terminology for dependencies in your FrintJS apps. We call them providers. Providers are any value that you can define in your FrintJS App, which can later be obtained by their unique names.
Creating a FrintJS app is as simple as:
import { createApp } from 'frint';
const MyApp = createApp({
name: 'MyAppName',
});
Below we will show you how providers can be defined in your App in three different ways.
You will find some similarities with Angular 2+, that’s because
frint
uses a fork ofdiyai
, which is a port of the Angular’s Injector API built in a way to be used without needing TypeScript
Known values
If you already know the value of your provider, you can use the useValue
property like this:
import { createApp } from 'frint';
const MyApp = createApp({
name: 'MyAppName',
providers: [
{
name: 'foo',
useValue: 'foo value here',
},
],
});
Now once you instantiate your App, you can get the foo
value as follows:
const app = new MyApp();
const foo = app.get('foo'); // `foo value here`
Generated values
There are times, when you don’t really know the value of your provider, and can only generate them when the App itself is instantiated. The useFactory
property can be used in those scenarios:
import { createApp } from 'frint';
const MyApp = createApp({
name: 'MyAppName',
providers: [
{
name: 'bar',
useFactory: function () {
return 'bar value here';
},
},
],
});
Now the bar
provider can be obtained from your App’s instance as follows:
const app = new MyApp();
const bar = app.get('bar'); // `bar value here`
Please note that, the function that generates bar
's value is only called once during the App’s instantiation. After that, it will keep returning the same cached value from the App’s internal registry of all providers.
Generated from ES6 classes
There are also cases, where you can also write your providers as ES6 classes first:
class Baz {
getValue() {
return 'baz value here';
}
}
To set ES6 classes as providers, we can use the useClass
property when defining them in FrintJS Apps:
import { createApp } from 'frint';
const MyApp = createApp({
name: 'MyAppName',
providers: [
{
name: 'baz',
useClass: Baz,
},
],
});
Now whenever your App gets instantiated, it will also instantiate the Baz
class, and set the instance as baz provider’s value.
const app = new MyApp();
const baz = app.get('baz'); // instance of Baz class
console.log(baz.getValue()); // `baz value here`
Similar to useFactory
, the class will be instantiated only once during your App’s instantiation and will return the same cached value every time you do app.get('baz')
.
Injecting providers in other providers
Now that we understand how providers can be defined in various ways in FrintJS Apps, we can go further into advanced use cases where one provider may depend on another provider.
From above examples, let’s say bar
provider needs to know the value of foo
. How do we inject foo
into bar
?
We can use the deps
(short for dependencies) property:
import { createApp } from 'frint';
const MyApp = createApp({
name: 'MyAppName',
providers: [
{
name: 'foo',
useValue: 'foo value here',
},
{
name: 'bar',
useFactory: function (deps) {
const { foo } = deps; // `foo value here`
return foo + ', bar value here';
},
deps: ['foo'],
},
],
});
This is what we just did above:
- Define
foo
provider - Define
bar
provider - For
bar
, listfoo
as a dependency - The function that generates
bar
value will now receive adeps
object with all its dependencies keyed by their names. Since we have listed onlyfoo
as a dependency, it will receivefoo
only for now. - The generated value of
bar
now returnsfoo value here, baz value here
.
You can try it yourself:
const app = new MyApp();
const foo = app.get('foo');
const bar = app.get('bar');
console.log(bar); // `foo value here, bar value here`
You can apply similar technique for useClass
too. The deps
object will then be given to the class as its first constructor argument:
class Baz {
constructor(deps) {
console.log(deps);
}
}
You can read further about it in the official docs for frint package here: https://frint.js.org/docs/packages/frint/.
Top comments (0)