Cloning Array the Right Way

ref – https://www.samanthaming.com/tidbits/92-6-use-cases-of-spread-with-array/

We want to clone an array, where changing a value in the new array does not affect the original array

original: [‘zero’, ‘one’]
newArray: [‘zero’, ‘one’]

So if we did this correctly, our original array shouldn’t be affected if we changed the newArray. Alright, let’s give this a try πŸ’ͺ

newArray is now: [‘zero’, ‘πŸ’©’]

original: [‘zero’, ‘one’] Great! original array is NOT affected

Using it in React’s Reducer

In React’s reducers, when we change property data of an array, React only does a value comparison of the object. If the two objects are different, it will update the DOM. If they stay the same, it doesn’t.

This works well for primitive values.

  • Are the two value’s Type same? √ string
  • Are the two values same? X one is richard, other is ricky

Update the DOM!!

But for objects it doesn’t work.

React literally does this: a === a

  • Are the two object’s Type same? √ Array
  • Are the two object’s values (in this case, address of the object) same? √

no change, no update of DOM. This is not what we want because we want the DOM to update so that we see age is 41, not 25.

No matter how much you change the object’s data, it will always stay the same if you do value comparisons.

In order to remedy this, we need to clone the array using spread syntax so that we get a new Array object (with its own address value) like so:

Now, React will do this:

  • Are the two object’s Type is Array? √
  • Are the two object’s address value same? X

Update the DOM!!!!

And this is exactly what we want.

MQTT – Message Queuing Telemetry Transport

ref –

  • https://emqx.medium.com/how-to-use-mqtt-in-the-react-project-1b04d80bd383
  • http://www.steves-internet-guide.com/mqtt/
  • http://www.steves-internet-guide.com/mqtt-hosting-brokers-and-servers/
  • http://www.steves-internet-guide.com/using-javascript-mqtt-client-websockets/
  • https://github.com/chkr1011/MQTTnet/issues/498

demo source

MQTT – Message Queuing Telemetry Transport.

The best way of understanding MQTT is to use it, and to do that you need two things:

  • An MQTT broker
  • An MQTT client

Rather than installing your own broker (mosquitto) I recommend that you first start with a public test broker like test.mosquitto.org or broker.emqx.io

its protocol may be: ws://
and port 8083

Now that we have a broker that will take in our messages…we should implement the MQTT client.

Implementing the MQTT client

Create a React Native App.


npx create-react-app react-mqtt-test –template typescript
npm install –save typescript @types/node @types/react @types/react-dom @types/jest
npm install mqtt –save

Note that you will encounter error
ERROR in ./node_modules/mqtt/lib/connect/index.js 7:12-26
Module not found: Error: Can’t resolve ‘url’ in ‘/Users/ricky_tsao/Desktop/jwt-react-rtk-query/node_modules/mqtt/lib/connect’

npm install url

(https://stackoverflow.com/questions/54392956/react-native-mqtt-module-url-does-not-exist-in-the-haste-module-map)

Next, under src, create components. Under components, create folder Hook.

Create index.js. Let’s create functional component called HookMqtt.
We create state hooks for our client, isSubscribed, payload, and connection status

HookMqtt

src/components/Hook/index.js

We declare a function where we use mqtt.connect for host and mqttOption. The reason why we do it here is because we need to update our client.

src/components/Hook/index.js

Notice setClient. When we connect, we update client with setClient, then the client variable can be used else where in HookMqtt functional component.

HookMqtt renders a UI like so:

Notice that it has four components:

  • Connection
  • Subscriber
  • Publisher
  • Receiver

Let’s talk about Connection first, as it is a component we need to be implemented to connect to our broker. Notice that Connect takes in prop mattConnect.

Connection

We want to pass in our previously created mqttConnect function into our connect prop parameter.

We will use this connect function to connect. However, let’s initialize url and options first.
First, in this class, we have a form, which initializes it via record.

src/components/Hook/Connection.js

We also have a record that has the basic connection properties of host, clientId, and port.
This is to connect to our free broker.

Next, we implement onFinish, which is a handler for when the user have filled out the form with user name and password.
We extract our connection information in order to form a url.

src/components/Hook/Connection.js

Options

We then create options object, which tells the broker what we want as far as the connection goes. Pay attention to clean and retain.

Clean property removes pending messages.

clean property means that we want to clean the session when we go offline. When this happens, then whatever pending QoS 1 and 2 messages that was published by other clients will not be there anymore.

We want to set clean to false so that we DO NOT clean the session when we go offline. That way, it still receives published Qos 1 and 2 messages when we go offline. When we log back on, we will see the messages.

By default clean is set to true. This means that when clients disconnect, whatever message that is published when they are offline will not be received when they sign back on.

src/components/Class/Connection.js

Normally if someone publishes a message to a topic, and no one is subscribed to that topic the message is simply discarded by the broker.

However the publisher can tell the broker to keep the last message on that topic by setting the retained message flag to true.

This can be very useful, as for example, if you have sensor publishing its status only when changed e.g. Door sensor. What happens if a new subscriber subscribes to this status?

Without retained messages the subscriber would have to wait for the status to change before it received a message.

However with the retained flat turned on, any subscribed client(s) would be able to get the
last retained message (current state of the sensor).

What is important to understand is that only one message is retained per topic.

Also, the next message published on that topic replaces the last retained message for that topic.

moving on, we add properties for authentication to our options. This way, we have url/options all ready to connect.

so we set our athentication user info onto options and then pass everything into connect.

Since the connect function is passed in by Mqtt, it will run this line to connect and then set the client object.

src/components/Hook/index.js

Back to HookMqtt. Now that we have a valid client to work with, let’s implement useEffect for when our client has changed to a new client.

When a new client comes onboard we have to make sure to get events so we can update our state when these happen:

src/components/Hook/index.js

  • connect status (connectStatus)
  • error status
  • reconnect status (connectStatus)
  • message status (payload)

We get the event updates via callbacks:

src/components/Hook/index.js

Now, when a client signs on, we can update our state payload and connectStatus when an event happens for that particular user.

Similar to how Connection is implemented, we’ll do the same for Publisher.

So in our functional component HookMqtt:

where mqttSub is:

It takes a subscription with the topic and qos data.
Now, where does topic come from?

In the Subscriber form, we have intiialValues with the record data:

where record data is:

topic and qos (in the Form) matches up to the ui controls. topic to textfield. qos to a pulldown. The options for the pulldown is dictated by qsOptioins.Provider, which gives us constant value context.

So that setups topic and qos defaults. If you use the pull down to select new qos, or type in new topic, the values parameter will be updated in onFinish.

Subscriber takes in prop sub and we call sub with our values. aka calling mqttSub.

In mqttSub, we see that:

it takes in a string topic, an options qos, and a callback for error anonymous function.

In client.d.ts, it is declared like so:

where IClientSubscribeOptions is defined as:

We need to put the qos to know what agreement is used between sender and receiver on the guarantee of delivering a message.

There are three levels.

  • 0 – client publish message, no acknowledgement from broker
  • 1 – sending is guaranteed. Broker will acknowledge. Client will re-send until it gets the broker’s acknowledgement
  • 2 – Sequence of 4 messages between sender and receiver (a kind of handshake) to confirm that message has been sent, and acknowledgement has been received. Both sender and receiver are sure that the message was sent exactly once.

Thus, client.subscribe will simply subscribe this client to the broker. And the broker will publish messages to this client in the future.

Receiving the Messages

Now looks at functional component Receiver.

In HookMqtt, it gives the state payload as prop into Receiver component.

and it updates the payload in useEffect:

The broker will be able to send messages to our client through the message event. Then we quickly update our payload.

In functional component Receiver, we append this new payload into our message queue.

where we render a List using this messages array:

Publishing Messages

In HookMqtt,

where

So following the interface defined for us, we give it a topic, a payload message, and options of type IClientPublishOptions where we set retain to true.

As mentioned earlier, retain to true means the user will get the last message. If we were to set this to false, then they will not.

Containment (component inside a component)

functional components are defined like so:

After importing it, you can call the component like in this example:

Some components don’t know their children ahead of time.

We recommend that such components use the special children prop to pass children elements directly into their output:

This lets other components pass arbitrary children to them by nesting the JSX:

Furthermore, you can use property extraction by using prop as an object and declaring the property that we’re looking for:

“Select” effect from Redux Saga

ref – https://stackoverflow.com/questions/38405700/getstate-in-redux-saga

We want to listen for DESERIALIZE actions. Once we detect one, we want to run function deserialize.

where deserialize is:

Problem is, how do we get state of the store?

The answer is that we can use select to the store’s state.

You can also declare a function that filters out what state properties you need, and select will literally “select” the data from the store for you

Basic Redux Saga

ref – https://medium.com/@ravindermahajan/why-use-redux-saga-f3413a3f7e34
https://redux-saga.js.org/docs/introduction/BeginnerTutorial/
https://redux-saga.js.org/docs/advanced/RacingEffects/
https://redux-saga.js.org/docs/advanced/RunningTasksInParallel/

source download

Reducers.js

First, we have reducers, which takes in actions, evaluate its type and return an updated state.
Reducers are executed whenever an action object is returned, or store.dispatch({…}) is executed

Component

Next we create an component. The component takes in four props. The current store value, an increment function, a decrement button, and async increment button. The component’s JSX has three buttons, each of which onclick will execute a passed in prop. Then it simply displays the store’s value.

Then let’s create a component Counter

Main

Now let’s first look at Main’s render function. It renders our Counter component with passed in values for props. Specifically, it passes in its store state for prop value.
On increment, it passes in an anonymous function that calls store.dispatch, which executes an action object with action type of INCREMENT or DECREMENT.

So our action types match up with what we have in reducer.

Adding in Redux Saga

Redux saga acts as a middleware that gives developers the scope to neatly separate any business logic, Ajax requests, data manipulation or any other operation which may not seem appropriate in reducers directly.

Original Working without redux saga:-
Action(s) β†’ Reducer(s)
With Redux saga as middleware:-
Action(s) β†’ Redux Saga β†’Reducer(s)

Benefits of using Saga:

  • Great support for Async Operations
  • It takes care of basic needs like cancelling previous saga operation on start of new eg: cancel previous xhr call on typeahead search query.
  • Can resolve a race between different effects (https://redux-saga.js.org/docs/advanced/RacingEffects/)
  • Running tasks in parallel like Promise.all (https://redux-saga.js.org/docs/advanced/RunningTasksInParallel/)
  • …and many other features

Let’s plug Saga into our simple application.
First, let’s create a Saga file.

Sagas are implemented as Generator functions that yield objects to the redux-saga middleware.

Saga

We implement a Promise that takes ms seconds to resolve. Once the Promise is resolved, the middleware will resume the Saga, executing code until the next yield.

We implement simple generator function that logs

We then create rootSaga function and yield all. This will execute all our saga functions when saga is run in main.js

In our example, we want to run helloSaga function that simply logs, and also execute a listener. This listener listens for action type INCREMENT_ASYNC.

Let’s implement this watchIncrementAsync

We use takeEvery, a helper function provided by redux-saga, to listen for store.dispatch({INCREMENT_ASYNC}) and run incrementAsync each time.

As you can see, it’s a listener that listens for INCREMENT_ASYNC. Once INCREMENT_ASYNC is dispatched by store.dispatch, then we execute incrementAsync.

Let’s implement incrementAsync

As mentioned previously, middleware will suspend the Saga until the Promise completes.
put is one example of what we call an Effect.
Effects are plain JavaScript objects which contain instructions to be fulfilled by the middleware.
put instructs the middleware to dispatch an action to the Store.

When a middleware retrieves an Effect yielded by a Saga, the Saga is paused until the Effect is fulfilled.

The action INCREMENT will reach reducer, where reducer will return state + 1.

Since the store is subscribed to the render, once the state changes, it will redraw and we’ll get an updated value.

install node manually from tar.gz files

You can uninstall and then install the node manually.

You have to download your current running version.

https://nodejs.org/dist/v12.12.0/

Download the node-v{your-current-version-number}.tar.gz, extract it and then go to command line.


cd node-v{your-current-version-number}
./configure
make
sudo make install

To uninstall it sudo make uninstall

Then download the version you want to install and follow same steps above.

Creating an iterator (js)

constructor, count:6


output:
6, 5, 4, 3, 2, 1