You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typically you explicitly communicate with effects from actions, by calling methods. But sometimes you need effects to know about the state of the application, or maybe some internal state in the effect should be exposed on your application state. Again we can take advantage of an **initialize** method on the effect:
Copy file name to clipboardExpand all lines: core/server-side-rendering.md
+53-1Lines changed: 53 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ Here we only export the configuration from the main Overmind file. The instantia
36
36
37
37
## Preparing effects
38
38
39
-
The effects will also be shared with the server. Typically this is not an issue, but you should be careful about creating effects that run logic when they are defined. You might also consider lazy-loading effects so that you avoid loading them on the server at all. You can read more about them in [EFFECTS](../core/running-side-effects.md).
39
+
The effects will also be shared with the server. Typically this is not an issue, but you should be careful about creating effects that run logic when they are defined. You might also consider lazy-loading effects so that you avoid loading them on the server at all. You can read more about them in [EFFECTS](running-side-effects.md).
If you are using state first routing, make sure you prevent the router from firing off the initial route, as this is not needed.
104
104
{% endhint %}
105
105
106
+
## OnInitialize
107
+
108
+
The `onInitialized` action does not run on the server. The reason is that it is considered a side effect you might not want to run, so we do not force it. If you do want to run an action as Overmind fires up both on the client and the server you can rather create a custom action for it.
109
+
110
+
{% tabs %}
111
+
{% tab title="overmind/actions.js" %}
112
+
```javascript
113
+
exportconstinitialize= () => {
114
+
// Whatever...
115
+
}
116
+
```
117
+
{% endtab %}
118
+
119
+
{% tab title="client/index.js" %}
120
+
```typescript
121
+
import { createOvermind } from'overmind'
122
+
import { config } from'./overmind'
123
+
124
+
const overmind =createOvermind(config)
125
+
overmind.actions.initialize()
126
+
```
127
+
{% endtab %}
128
+
129
+
{% tab title="server/index.js" %}
130
+
```javascript
131
+
import { createOvermindSSR } from'overmind'
132
+
import { config } from'../client/overmind'
133
+
134
+
exportdefaultasync (req, res) => {
135
+
constovermind=createOvermindSSR(config)
136
+
awaitovermind.actions.initialize()
137
+
138
+
consthtml=renderToString(
139
+
// Whatever implementation your view layer provides
Copy file name to clipboardExpand all lines: faq.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,5 +8,9 @@ First… try to refresh your app to reconnect. If this does not work make sure t
8
8
9
9
Restart VS Code
10
10
11
+
## My operator actions are not running?
12
+
13
+
Operators are identified with a Symbol. If you happen to use Overmind across packages you might be running two versions of Overmind. The same goes for core package and view package installed out of version sync. Make sure you are only running on package of Overmind by looking into your **node\_modules** folder.
Copy file name to clipboardExpand all lines: guides-1/testing.md
+11-29Lines changed: 11 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,22 +11,18 @@ You can also do **unit testing** of actions and effects. This will cover expecte
11
11
When you write tests you will create many instances of a mocked version of Overmind with the configuration you have created. To ensure that this configuration can be used many times we have to separate our configuration from the instantiation of the actual app.
12
12
13
13
{% tabs %}
14
-
{% tab title="overmind/index.ts" %}
14
+
{% tab title="overmind/index.js" %}
15
15
```typescript
16
16
import { IConfig } from'overmind'
17
17
import { state } from'./state'
18
18
19
19
exportconst config = {
20
20
state
21
21
}
22
-
23
-
declaremodule'overmind' {
24
-
interfaceConfigextendsIConfig<typeofconfig> {}
25
-
}
26
22
```
27
23
{% endtab %}
28
24
29
-
{% tab title="index.ts" %}
25
+
{% tab title="index.js" %}
30
26
```typescript
31
27
import { createOvermind } from'overmind'
32
28
import { config } from'./overmind'
@@ -43,11 +39,9 @@ Now we are free to import our configuration without touching the application ins
43
39
When testing an action you’ll want to verify that changes to state are performed as expected. To give you the best possible testing experience Overmind comes with a mocking tool called **createOvermindMock**. It takes your application configuration and allows you to run actions as if they were run from components.
44
40
45
41
{% tabs %}
46
-
{% tab title="overmind/actions.ts" %}
42
+
{% tab title="overmind/actions.js" %}
47
43
```typescript
48
-
import { AsyncAction } from'overmind'
49
-
50
-
exportconst getPost:AsyncAction<string> =async ({ state, api }, id) {
You might want to test if a thrown error is handled correctly here. This is an example of how you could do that:
64
58
65
59
{% tabs %}
66
-
{% tab title="overmind/actions.test.ts" %}
60
+
{% tab title="overmind/actions.test.js" %}
67
61
```typescript
68
62
import { createOvermindMock } from'overmind'
69
63
import { config } from'./'
@@ -114,7 +108,7 @@ If your actions can result in multiple scenarios a unit test is beneficial. But
114
108
You do not have to explicitly write the expected state. You can also use for example [JEST](https://www.overmindjs.org/guides/intermediate/05_writingtests?view=react&typescript=true) for snapshot testing. The mock instance has a list of mutations performed. This is perfect for snapshot testing.
115
109
116
110
{% tabs %}
117
-
{% tab title="overmind/actions.test.ts" %}
111
+
{% tab title="overmind/actions.test.js" %}
118
112
```typescript
119
113
import { createOvermindMock } from'overmind'
120
114
import { config } from'./'
@@ -162,7 +156,7 @@ In this scenario we would also ensure that the **isLoadingPost** state indeed fl
162
156
The **onInitialize** hook will not trigger during testing. To test this action you have to trigger it yourself.
163
157
164
158
{% tabs %}
165
-
{% tab title="overmind/onInitialize.test.ts" %}
159
+
{% tab title="overmind/onInitialize.test.js" %}
166
160
```typescript
167
161
import { createOvermindMock } from'overmind'
168
162
import { config } from'./'
@@ -197,29 +191,17 @@ A simple example of this is doing requests. Maybe you want to use e.g. [AXIOS](h
197
191
This is just an example showing you how you can structure your code for optimal testability. You might prefer a different approach or maybe rely on integration tests for this. No worries, you do what makes most sense for your application:
198
192
199
193
{% tabs %}
200
-
{% tab title="overmind/effects.ts" %}
194
+
{% tab title="overmind/effects.js" %}
201
195
```typescript
202
196
import*asaxiosfrom'axios'
203
-
import { Post } from'./state'
204
-
205
-
interfaceIRequest {
206
-
get<T>(url:string):Promise<T>
207
-
}
208
-
209
-
interfaceIOptions {
210
-
authToken:string
211
-
baseUrl:string
212
-
}
213
197
214
198
// This is the class we can create new instances of when testing
Copy file name to clipboardExpand all lines: introduction.md
+9-5Lines changed: 9 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,11 @@ If you rather want to go right ahead and set up a local project, please have a l
8
8
9
9
Before we move on, have a quick look at this sandbox. It is a simple counter application and it gives you some foundation before talking more about Overmind and building applications.
We have now separated out the Overmind related logic into its own file, **app.js**. This file creates the Overmind instance and also exports how the components will interact with the state and the actions, the hook called **useApp**. Vue and Angular has other mechanisms conventional to those frameworks where application state and actions can be accessed.
99
103
@@ -183,7 +187,7 @@ Any function you insert into the state tree is treated as derived state. That me
183
187
184
188
Now let us move into an even more complex application. Here we have added **effects**. Specifically effects to handle routing, storing todos to local storage and producing unique ids for the todos. We have added an **onInitialize** hook which is a special function Overmind runs when the application starts.
You can think of effects as a contract between your application and the outside world. You write an effect API of **what** your application needs and some 3rd party tool or native JavaScript API will implement **how** to provide it. Let us look at the router:
189
193
@@ -223,7 +227,7 @@ This argument passed is transformed into something Page can understand. What thi
223
227
224
228
Defining all the state, actions and effects on one object would not work very well for a large application. A convention in Overmind is to split these concepts into different files behind folders representing a domain of the application. In this next sandbox you can see how we split up state, actions and effects into different files. They are all exposed through a main file representing that domain, in this case “the root domain”:
Also notice that we have split up the instantiation of Overmind from the definition of the application. What this allows us to do is reuse the same application configuration for testing purposes and/or server side rendering. We separate the definition from the instantiation.
229
233
@@ -239,7 +243,7 @@ Have a look at this new project where we have typed the application:
239
243
You have to **OPEN IN EDITOR** to get the full Typescript experience.
As you can see we only have to add an **Action** type to our functions and optionally give it an input type. This is enough for the action to give you all information about the application. Try changing some code and even add some code to see how Typescript helps you to explore the application and ensure that you implement new functionality correctly.
Copy file name to clipboardExpand all lines: quickstart.md
+11-32Lines changed: 11 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,7 @@ export const state = {
35
35
```
36
36
{% endtab %}
37
37
38
-
{% tab title="overmind/index.ts" %}
38
+
{% tab title="overmind/index.js" %}
39
39
```typescript
40
40
import { state } from'./state'
41
41
@@ -44,41 +44,20 @@ export const config = {
44
44
}
45
45
```
46
46
{% endtab %}
47
-
{% endtabs %}
48
-
49
-
And fire up your application in the browser or whatever environment your user interface is to be consumed in by the users.
50
-
51
-
### VS Code
52
-
53
-
For the best experience you should install the [OVERMIND DEVTOOLS](https://marketplace.visualstudio.com/items?itemName=christianalfoni.overmind-devtools-vscode) extension. This will allow you to work on your application without leaving the IDE at all.
54
-
55
-

56
-
57
-
{% hint style="info" %}
58
-
If you are using the **Insiders** version of VSCode the extension will not work. It seems to be some extra security setting.
59
-
{% endhint %}
60
-
61
-
### Devtool app
62
47
63
-
Alternatively you can install the standalone application of the devtools. It is highly recommended to install the package [CONCURRENTLY](https://www.npmjs.com/package/concurrently). It allows you to start the devtools as you start your build process:
And fire up your application in the browser or whatever environment your user interface is to be consumed in by the users.
80
59
81
-
### Hot Module Replacement <aid="quickstart-hot-module-replacement"></a>
60
+
Move on with the specific view layer of choice to connect your app:
82
61
83
-
A popular concept introduced by Webpack is [HMR](https://webpack.js.org/concepts/hot-module-replacement/). It allows you to make changes to your code without having to refresh. Overmind automatically supports HMR. That means when **HMR**is activated Overmind will make sure it updates and manages its state, actions and effects. Even the devtools will be updated as you make changes.
0 commit comments