Show stash

ref – https://stackoverflow.com/questions/3573623/how-do-i-preview-stash-contents-in-git

git stash show -p stash@{0}

To apply a specific stash:

git stash apply stash@{0}

Record audio in React

ref – https://codesandbox.io/s/audio-experiments-w7yz8?file=/src/App.js:0-2208

How node returns user with token to React

We start off on the frontend, where we submit some data.

frontend – src/pages/Register.jsx

we dispatch register with userData, via createAsyncThunk. createAsyncThunk creates an async request. It generates promise lifecycle action types pending/fulfilled/rejected.

We start the process by defining a payload creator, which is the anon function provided to createAsyncThunk. It tries to execute our authServer.register function.

frontend – src/features/auth/authSlice.js

This allows us to use axios’s post and hit the URL with the body data.

frontend – src/features/auth/authService.js

The request is received on the backend.

When we request to register a user, Node receives the request and data in the body.
If the username doesn’t exist, it would create the user, and then generate a token.
It would return the newly created user data and the generated token back to the front end.

backend – backend/controllers/userController.js

In order to generate the token, it would take the user’s id, the JWT_SECRET string, and create a token by using the sign function.

JWTs can be signed using a secret (in our case JWT_SECRET string) with the HMAC algorithm.
It will spit back a long jwt token string.

This string can only be decrypted with the same string.

The reason why we do this is because we want the front end to use the same token and send it back to use, which needs to be decrypted by using the same JWT_SECRET:

backend/middleware/authMiddleware.js

We can then get the user’s id and find it in our database. This ensures that the client making the request is someone we have dealt with before.

Newly created user and token arrives in React

we return the data to the async anon function that is the 2nd parameter of createAsyncThunk:

This will return to our state’s user object via action.payload when our register thunk’s promise has been fullfilled:

This is how our thunkAPI’s can access the token from its user object in the state.

The thunk can access the store (getState) and accesses its reducer auth, which then accesses its state property user, and finally, the token property.

The user comes from the state:

And the auth is the reducer’s property name in the store:

Lazy load component (w/ Suspense) in React

ref – https://beta.reactjs.org/reference/react/lazy#suspense-for-code-splitting

Lazy-loading components with Suspense

Usually, you import components with the static import declaration:

To defer loading this component’s code until it’s rendered for the first time, replace this import with:

Now that your component’s code loads on demand, you also need to specify what should be displayed while it is loading. You can do this by wrapping the lazy component or any of its parents into a boundary:

the code for MarkdownPreview won’t be loaded until you attempt to render it. If MarkdownPreview hasn’t loaded yet, Loading will be shown in its place.

First let’s look at a function delayForDemo that will delay the the lazy loading of our MarkdownPreview.

The import() returns a Promise that will be fulfilled once the module is loaded completely.

Hence, our parameter of promise receives imported components.
We do a timeout of 2 seconds, and then return the promise right after.

We then use it on the import like so:

The whole point of this is to show that while an import component is being lazy loaded, we must show the fallback Loading component.

Notice

Why do we need middleware for async flow in redux

ref – https://stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-async-flow-in-redux

Why do we need middleware for async flow in redux?

…for example, Why can’t the container component call the async API, and then dispatch the actions?

Solution

There is nothing wrong with this approach. It’s just inconvenient in a large application because you’ll have different components performing the same actions, you might want to:

  • debounce some actions
  • or keep some local state like auto-incrementing IDs close to action creators
  • etc.
  • So it is just easier from the maintenance point of view to extract action creators into separate functions.

    Therefore, the benefit of using middleware like Redux Thunk or Redux Promise is that components aren’t aware of how action creators are implemented

    and whether they care about Redux state,
    whether they are synchronous or asynchronous,
    and whether or not they call other action creators.

    The downside is a little bit of indirection, but we believe it’s worth it in real applications.

    Using middleware – By using middle are for async management, component doesn’t care that the action creator is async. It just calls dispatch normally, it can also use mapDispatchToProps to bind such action creator with a short syntax, etc. The components don’t know how action creators are implemented, and you can switch between different async approaches (Redux Thunk, Redux Promise, Redux Saga) without changing the components.

    Custom way (implement it by hand) – On the other hand, explicit approach, your components know exactly that a specific call is async, and needs dispatch to be passed by some convention (for example, as a sync parameter).

    Also think about how this code will change. Say we want to have a second data loading function, and to combine them in a single action creator.

    We need to be mindful of what kind of action creator we are calling:

    With Redux Thunk action creators can dispatch the result of other action creators and not even think whether those are synchronous or asynchronous:

    If you need to change it to be synchronous, you can also do this without changing any calling code:

debounce

ref – https://www.freecodecamp.org/news/javascript-debounce-example/

Upon first click, debounce function returns a function.

This function goes onto the local stack.
It has a local timer variable that points to a setTimeout.
Initially, its suppose to execute our function parameter after 300 ms.

We simulate a button click by executing this function reference.

But if within the 300 ms the user clicks again (a second click!).
Thus, a SECOND debounce function call will return a 2nd function that gets pushed onto the local stack. The 2nd function will then execute and using clearTimeout will clear the previously set timer from the FIRST CLICK.

Then, the first setTimeout finishes executing (because it was just cleared by our 2nd click) and gets popped from the stack.

So now, only our 2nd click’s inner function is executing on the local stack. Its timer is processing the 300 ms via setTimeout. If we do not click again, then the 300 ms will finish, and thus our saveInput will execute..successfully finishing this debounced operation.

1) start, put func inside debounce parameter
2) — debounce called —
3) return you a function reference
4) Executing function reference!
5) inner function start: CLEAR PREVIOUSLY set timer
set new timer for 300 ms
6) 300 ms over, lets execute the func
Saving data… test

Non serializable value was detected in an action

The issue here is that on our client, say we update a word like so:

Because when dispatch our updateWord function, if we were to return a Promise object…

…it will be assigned to state’s wordData, which is a violation because state can only take serializable value.

src/features/words/wordSlice.js

A Promise is not serializable, so thus it will give an error like so: