Saturday, July 31, 2021

Wait for State Changes with Redux Saga

Hello,

As we know Redux saga allows us to respond to actions outside Redux store. It's kind of middleware library to handle side effects with ease. This side effect could be anything like calling APIs, doing some IO operations or anything. While working with Saga sometime it happens that we also want to detect state changes and do some actions after it. In this blog I am going to explain how you can wait or detect Redux state changes with Saga.

Let's understand with an example. For example there is an API call to get access token and as soon as you have access toke available in state you want to call some other actions like background sync etc. 


function* waitForLoginToken(selector) {

    if (yield select(selector)) return;

    while (true) {

      yield take('*');

      if (yield select(selector)) return;

    }

}

export function* postSignInAction(payload) {

    cost loginTokenSelector = state => state.auth.loginToken;

    yield call(waitForLoginToken, loginTokenSelector);

    yield put({ type: 'BACKGROUND_SYNC' });

}

function* mySaga(){

  yield takeEvery('SIGN_IN', postSignInAction);

}

As you can see in above code, we take every sign in action and call postSignInAction which will wait for state change.

We defined state selector as state.auth.loginToken. Till the time loginToken is not set in state.auth it will wait as we are using while loop to wait for state change. Once we get it in state we call next action. 

This way you can & detect state change with Redux Saga. Hope this helps you.

Saturday, July 17, 2021

React-Draft-Wysiwyg - Find Text Option

Hello,

Recently I was working on POC for rich text editor using React-Draft-Wysiwyg editor. 

There we have a requirement to add find & replace dialog box which should find the matching text from all the blocks and height it with background color. For the POC we added find text functionality. Here in this blog I will explain how to do it. 

For this I have created separate React component and add it as custom option to editor toolbar. Let's understand it step by step. 

If you want to know how to add custom option you can find reference from here.

https://jpuri.github.io/react-draft-wysiwyg/#/docs

1) Create Modal with Text input and Button

Please note I have used grommet UI library to build the POC. So text input and button was imported from Grommet.

<TextInput

    data-cy="find-text"

    autoFocus

    onChange={this.onChangeFindText}

    value={this.state.findText}

/>

<Button

    id="find"

    label="Find"

    onClick={this.onFindClick}

/>

2) Handle Find Click Event

onFindClick = () => {

  const search = this.state.findText;

  let contentState = convertToRaw(this.props.editorState.getCurrentContent());

  contentState.blocks.forEach(block => {

    const text = block.text;

    const matches = [...text.matchAll(search)];

    if(matches.length > 0) {

      matches.forEach(match =>{

        block.inlineStyleRanges.push({length: match[0].length,

          offset: match.index,

          style: "bgcolor-rgb(247,218,100)"

        })

      });

    }

  });

  let newEditorState = {

    editorState: EditorState.createWithContent(convertFromRaw({blocks: contentState.blocks,entityMap: {}})),

    contentState: null

  }

  this.props.onChange(EditorState.createWithContent(convertFromRaw({blocks: contentState.blocks,entityMap: {}})));

}

In above code we are getting search text from the state and matching it with texts of all custom blocks. Where ever it matches we are setting inline styles in blocks with yellow color background. and then setting state of editor again with new blocks. 

Hope this helps you.

Sunday, July 4, 2021

Docker MongoDB terminates when it runs out of memory

When you have multiple services running in docker container it's quite possible that you have an issues with certain services when your docker container runs out of memory. MongoDB is one such service. 

On docker container when you have MongoDB running and when it starts storing huge data it starts consuming lots of memory and that's where you have an issue. MongoDB will crash after sometime where isn't much memory left. 

The reason behind this is the IO model of MongoDB, it tries to keep as much data as possible in cache so read and write operations are much faster. But this creates an issue with docker as we have limited memory and lots of services are sharing that. 

Starting from MongoDB 3.2 on words WiredTiger storage engine is the default one for MongoDB and it's recommended. 

There are various advantages of WiredTiger storage engine. For example,

  • Document Level Concurrency
  • Snapshots and Checkpoints
  • Journal
  • Compression
  • Memory Use
One of most useful feature is Memory use. 

With WiredTiger, MongoDB utilizes both the WiredTiger internal cache and the filesystem cache.

You can control it with --wiredTigerCacheSizeGB configuration.

The --wiredTigerCacheSizeGB limits the size of the WiredTiger internal cache. The operating system will use the available free memory for filesystem cache, which allows the compressed MongoDB data files to stay in memory. In addition, the operating system will use any free RAM to buffer file system blocks and file system cache.

With this setting you can enhance memory usage. MongoDB will not use excessive memory and with heavy data usage on docker container MongoDB will not crash on excessive memory usage.

Hope this helps you.