tag:blogger.com,1999:blog-74420721507650226102024-03-14T14:17:48.378+05:30Hiren's Technical BlogI am a developer and I know how hard it is to solve difficult issues while programming in case you did not get any help. I have faced this so many times. That's why I started this blog so that I can share problems and solutions with developer community. In case if you face any issue in programming do check my blog once, it will surely save your time. Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.comBlogger336125tag:blogger.com,1999:blog-7442072150765022610.post-51200167471871134412022-10-02T16:45:00.003+05:302022-10-02T16:45:35.772+05:30NodeJs Read XML file and Parse Data<p>Hello,</p><p>Few days back I worked on task to read XML file in NodeJs and parse the data and convert data to the JSON format. Here in this blog I am going explain how I did achieved this. </p><p>Following is our sample XML file.</p><p><b><root></b></p><p><b> <parent></b></p><p><b> <firstchild>First Child Content 1</firstchild></b></p><p><b> <secondchild>Second Child Content 1</secondchild></b></p><p><b> </parent></b></p><p><b> <parent></b></p><p><b> <firstchild>First Child Content 2</firstchild></b></p><p><b> <secondchild>Second Child Content 2</secondchild></b></p><p><b> </parent></b></p><p><b></root></b></p><p><span style="font-size: medium;"><b>Step 1 : Install necessary NPM packages</b></span></p><p>First install following packages in your NodeJs application.</p><p>npm install --save xmldom</p><p>mpm install --save hashmap</p><p>Here xmldom is the package we are going to use to parse the XML data and hasmap package we are going to use to convert and save data in JSON format.</p><p><span style="font-size: medium;"><b>Step 2 : Import necessary packages in script</b></span></p><p><span style="font-size: large;">const { readFile } = require('fs/promises');</span></p><p><span style="font-size: medium;">const xmldom = require('xmldom');</span></p><p></p><p><span style="font-size: medium;">const HashMap = require('hashmap');</span></p><p><span style="font-size: large;">We are going to use readFile from fs/promises. Also we will use xmldom to parse the string data. xmldom is a </span><span style="font-size: medium;"><b>A JavaScript implementation of W3C DOM for Node.js, Rhino and the browser. Fully compatible with W3C DOM level2; and some compatible with level3. Supports DOMParser and XMLSerializer interface such as in browser.</b></span></p><p><b style="font-size: large;">Step 3 : Read the XML file</b></p><p><span style="font-size: medium;">const readXMLFile = async()=> {</span></p><p><span style="font-size: medium;"><span style="white-space: pre;"> </span>var parser = new xmldom.DOMParser();</span></p><p><span style="font-size: medium;"> const result = await readFile('./data.xml',"utf8");</span></p><p><span style="font-size: large;"></span></p><p><span style="font-size: medium;"> const dom = parser.parseFromString(result, 'text/xml');</span></p><p><span style="font-size: medium;">}</span></p><p>Here we are using async function to read the XML file as we want to wait till XML file is completely finished. Also we created a <span style="font-size: large;">xmldom.DOMParser which we will use to parse the string data of the file. This parser will give you all the TAGs of the XML file just like we access standard HTML tags. With this we can use </span><span style="font-size: medium;">getElementsByTagName to get XML tags. </span> </p><p><b style="font-size: large;">Step 4 : Convert XML data to hasmap</b></p><p><span style="font-size: medium;">const readXMLFile = async()=> {</span></p><p><span style="font-size: medium;"><span style="white-space: pre;"> </span>var parser = new xmldom.DOMParser();</span></p><p><span style="font-size: medium;"><span> </span><span> </span>const dataMap = new HashMap();</span></p><p><span style="font-size: medium;"> const result = await readFile('./data.xml',"utf8");</span></p><p><span style="font-size: large;"></span></p><p><span style="font-size: medium;"> const dom = parser.parseFromString(result, 'text/xml');</span></p><p><span style="font-size: medium;"><span> </span><span> </span>var parentList = dom.getElementsByTagName("</span>parent<span style="font-size: medium;">");</span></p><p><span style="font-size: medium;"><span> </span><span> </span>for(var i =0; i < </span><span style="font-size: large;">parentList</span><span style="font-size: medium;">.length; i++) {</span></p><p><span style="font-size: medium;"> <span style="white-space: pre;"> <span> </span></span>const parent = </span><span style="font-size: large;">parentList</span><span style="font-size: medium;">[i];</span></p><p><span style="font-size: medium;"><span> </span><span> </span><span> </span>const firstchild = </span><span style="font-size: large;">parent</span><span style="font-size: medium;">.getElementsByTagName("</span>firstchild<span style="font-size: medium;">")[0].textContent;</span></p><p><span style="font-size: medium;"> <span style="white-space: pre;"> <span> </span></span>const secondchild = </span><span style="font-size: large;">parent</span><span style="font-size: medium;">.getElementsByTagName("</span>secondchild<span style="font-size: medium;">")[0].textContent;</span></p><p><span style="font-size: medium;"><span> </span><span> </span><span> </span>const parentMap = new HashMap();</span></p><p><span style="font-size: medium;"> <span style="white-space: pre;"> <span> </span></span></span><span style="font-size: large;">parentMap</span><span style="font-size: medium;">.set("</span><span style="font-size: large;">firstchild</span><span style="font-size: medium;">",</span><span style="font-size: large;"> firstchild</span><span style="font-size: medium;">);</span></p><p><span style="font-size: medium;"> <span style="white-space: pre;"> <span> </span></span></span><span style="font-size: large;">parentMap</span><span style="font-size: medium;">.set("</span><span style="font-size: large;">secondchild</span><span style="font-size: medium;">",</span><span style="font-size: large;"> secondchild</span><span style="font-size: medium;">);</span></p><p><span style="font-size: medium;"><span> </span><span> </span><span> </span>dataMap.set(i, </span><span style="font-size: large;">parentMap</span><span style="font-size: medium;">);</span></p><p><span style="font-size: large;"> </span><span style="font-size: large;"> }</span></p><p><span style="font-size: medium;">}</span></p><div><br /></div><div><span style="font-size: medium;">In the above function we got list of parents by getElementsByTagName method and then we are iterating through it and accessing the child tags and getting it's text content. Then we are simply storing it in hasmap with unique key. </span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;">Hope this helps you.</span></div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-35254422272404686292022-07-03T11:25:00.001+05:302022-07-05T16:08:04.178+05:30Mock node-fetch with JEST<p>Recently I tried my hands on Jest - the popular JavaScript Testing Library. In my application we were using node-fetch to make API calls. I used Jest to mock and test this API calls. Here in this blog I will explain on how to mock node-fetch with Jest. </p><p>Following is my function to call the GET API. </p><p><b>fetch_get.js</b></p><p>const fetch = require('node-fetch');</p><p>module.exports = async () => {</p><p> return await fetch('http://YOUR_GET_URL').then(res => res.json());</p><p>};</p><div>Now to test this create a test file with name <b>test.fetch_get.js</b></div><div><b><br /></b></div><div><b>Step 1: First import the function.</b></div><div><br /></div><div><div>const fetch_get = require('../fetch_get');</div></div><div><br /></div><div><br /></div><div><b>Step 2 : Mock the node-fetch with Jest</b></div><div><div><br /></div><div>const fetch = require('node-fetch');</div></div><div><div>jest.mock('node-fetch', ()=>jest.fn())</div></div><div><br /></div><div><b>Step 3: Create Mock response</b></div><div><b><br /></b></div><div><div>const mockedRes = {</div><div> "success": true,</div><div> "data": [</div><div> {</div><div> id: 1,</div><div> text: 'Test Data 1'</div><div> },</div><div> {</div><div> id: 1,</div><div> text: 'Test Data 2'</div><div> }</div><div> ]</div><div>};</div></div><div><br /></div><div><b>Step 4: Add Test </b></div><div><br /></div><div><div>describe("Test get fetch", () => {</div><div> let data;</div><div> it('It should return the data', () => {</div><div><span> </span><span> </span>const response = Promise.resolve({</div><div> ok: true,</div><div> status: 200,</div><div> json: () => {</div><div> return mockedRes;</div><div> },</div><div> });</div><div> fetch.mockImplementation(()=> response)</div><div> data = await fetch_get();</div><div> expect(data).toEqual(mockedRes);</div><div> });</div><div>});</div></div><div><br /></div><div>In above code we have created a rest and mocked the response to return our response when we call .json() method for response. Then we are simply comparing the response. This is a very simple test. Here in stead of comparing data, you may have other tests like checking length of data or checking specific data etc.</div><div><br /></div><div><b>Step 5: Run Test</b></div><div><br /></div><div>Run the test with npm test or npm run test and you will see the following result.</div><div><br /></div><div><div>Test get fetch</div><div> ✓ It should return the data (17 ms)</div><div><br /></div><div>Test Suites: 1 passed, 1 total</div><div>Tests: 1 passed, 1 total</div><div>Snapshots: 0 total</div><div>Time: 0.313 s, estimated 1 s</div></div><div><br /></div><div>Hope this helps you.</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-63464881188114944552022-01-29T16:32:00.001+05:302022-01-29T16:33:17.256+05:30How to Execute Shell Script from Dockerfile<p>Recently I faced a problem with Docker build. Before we build the image there was a requirement to cleanup something from MongoDB. For that we tried to create shell script and execute it from Dockerfile before we start the service. Here in this blog I will explain how you can execute the shell script from Dockerfile. </p><p>For that first create the shell script in the same context of Dockerfile. That means the file should be in the same folder or subfolder where Dockerfile is there. </p><p>We can not access file outside the Docker build context so file has to be in the same folder.</p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">nano test.sh</span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;">You can put your content in this file for the tasks you want to do with this file. </span></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;"><br /></span></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;">Now first we will copy the file in docker build context. So that it can be executed. This step is mandatory or else it will not find file. Add following lines of code in your Dockerfile.</span></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;"><br /></span></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">FROM alpine3.15</span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">COPY test.sh ./test.sh</span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Next step we have to change access rights of the script so it can be executed.</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">RUN chmod +x ./test.sh</span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Now since we have file in the Docker build context and it has proper access rights we can execute the file. </p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">RUN sh ./test.sh</span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 21px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">That's it and now when to service starts it will execute the file and do all the actions which you have added in shell script.</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Hope this helps you. </p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-91027787561809160342022-01-03T21:44:00.003+05:302022-01-03T21:44:29.811+05:30Kubernetes ImagePullBackOff error<p>Recently I faced an issue while working Kubernetes cluster. I was trying to build docker image from local repository to test some changes in production before we merge the code. After building the docker image and recreating the container it was showing ImagePullBackOff error when I check the status with </p><p><b><span style="font-size: medium;">kubectl get pods</span></b></p><p>In this blog I am going to mention the possible cause for this error and will explain the resolution which worked for me.</p><p>In a Kubernetes, there’s an agent on for node which is called kubelet. This is responsible for running containers in the nodes. For some reason if image can't be pulled the kublet will throw ImagePullBackOff error. </p><p>There are some possible reasons for this when kubectl is not able to pull image from mentioned registry. </p><p>Either image or tag is not available. </p><p>The name of the image or tag is wrong in deployment yaml file</p><p>kubectl does not have access to image registry. </p><p>In my case there was no such issues mentioned above. The image with tag was there. I have specified the correct name in deployment yaml file and because it was a local registry, there was no need of authentication. </p><p>So here is how I solved this issue. I set image pull policy to following value in my deployment yaml file.</p><p><b>imagePullPolicy: IfNotPresent</b></p><div>The reason it worked is, the kubectl was trying to find image in registry but it was not present because it was local registry so then it tried to find image in local repository and caches it. </div><div><br /></div><div>This solution worked for me because I was using local registry. If you are facing such issue try setting above value to imagePullPolicy and it may work. Hope this helps you.</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-48328174560411674152021-07-31T15:14:00.002+05:302021-07-31T15:14:49.565+05:30Wait for State Changes with Redux Saga<p>Hello,</p><p>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.</p><p>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. </p><p><br /></p><p>function* waitForLoginToken(selector) {</p><p> if (yield select(selector)) return;</p><p> while (true) {</p><p> yield take('*');</p><p> if (yield select(selector)) return;</p><p> }</p><p>}</p><p>export function* postSignInAction(payload) {</p><p><span> </span>cost loginTokenSelector = state => state.auth.loginToken;</p><p><span> </span>yield call(waitForLoginToken, loginTokenSelector);</p><p><span> </span>yield put({ type: 'BACKGROUND_SYNC' });</p><p>}</p><p>function* mySaga(){</p><p> yield takeEvery('SIGN_IN', postSignInAction);</p><p>}<br /></p><p>As you can see in above code, we take every sign in action and call postSignInAction which will wait for state change.</p><p>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. </p><p>This way you can & detect state change with Redux Saga. Hope this helps you.</p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com1tag:blogger.com,1999:blog-7442072150765022610.post-4670665950724179862021-07-17T16:08:00.003+05:302021-07-17T16:08:25.476+05:30React-Draft-Wysiwyg - Find Text Option<p>Hello,</p><p>Recently I was working on POC for rich text editor using <a href="https://github.com/jpuri/react-draft-wysiwyg" target="_blank">React-Draft-Wysiwyg</a> editor. </p><p>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. </p><p>For this I have created separate React component and add it as custom option to editor toolbar. Let's understand it step by step. </p><p>If you want to know how to add custom option you can find reference from here.</p><p><a href="https://jpuri.github.io/react-draft-wysiwyg/#/docs">https://jpuri.github.io/react-draft-wysiwyg/#/docs</a></p><p><b>1) Create Modal with Text input and Button</b></p><p>Please note I have used grommet UI library to build the POC. So text input and button was imported from Grommet.</p><p><TextInput</p><p> data-cy="find-text"</p><p> autoFocus</p><p> onChange={this.onChangeFindText}</p><p> value={this.state.findText}</p><p>/></p><p><Button</p><p> id="find"</p><p> label="Find"</p><p> onClick={this.onFindClick}</p><p>/></p><p><b>2) Handle Find Click Event</b></p><p>onFindClick = () => {</p><p> const search = this.state.findText;</p><p> let contentState = convertToRaw(this.props.editorState.getCurrentContent());</p><p> contentState.blocks.forEach(block => {</p><p> const text = block.text;</p><p> const matches = [...text.matchAll(search)];</p><p> if(matches.length > 0) {</p><p> matches.forEach(match =>{</p><p> block.inlineStyleRanges.push({length: match[0].length,</p><p> offset: match.index,</p><p> style: "bgcolor-rgb(247,218,100)"</p><p> })</p><p> });</p><p> }</p><p> });</p><p> let newEditorState = {</p><p> editorState: EditorState.createWithContent(convertFromRaw({blocks: contentState.blocks,entityMap: {}})),</p><p> contentState: null</p><p> }</p><p> this.props.onChange(EditorState.createWithContent(convertFromRaw({blocks: contentState.blocks,entityMap: {}})));</p><p>}</p><p>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. </p><p>Hope this helps you.</p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-18576858774215457332021-07-04T15:55:00.000+05:302021-07-04T15:55:21.938+05:30Docker MongoDB terminates when it runs out of memory<p>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. </p><p>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. </p><p>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. </p><p>Starting from MongoDB 3.2 on words WiredTiger storage engine is the default one for MongoDB and it's recommended. </p><p>There are various advantages of WiredTiger storage engine. For example,</p><p></p><ul style="text-align: left;"><li>Document Level Concurrency</li><li>Snapshots and Checkpoints</li><li>Journal</li><li>Compression</li><li>Memory Use</li></ul><div>One of most useful feature is Memory use. </div><div><br /></div><p></p><div>With WiredTiger, MongoDB utilizes both the WiredTiger internal cache and the filesystem cache.</div><div><br /></div><div>You can control it with <b>--wiredTigerCacheSizeGB</b> configuration.</div><div><br /></div><div><div>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.</div><div><br /></div></div><div>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.</div><div><br /></div><div>Hope this helps you.</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-76590027022318061702021-07-04T15:15:00.001+05:302021-07-04T15:15:41.585+05:30ReactJs Peer to Peer Communication<p>Recently I evaluated peer to peer communication approach for one of my project so here I am going to share it and how you can use it in your project in case you want to implement peer to peer communication in your project. </p><p>We used library called <a href="https://peerjs.com/" target="_blank">PeerJS</a> , it's simple peer to peer built on top of webRTC. For this first you have to create a server, which will act as only connection broker. No peer to peer data goes through this server. Let's just create a simple server.</p><p>Let's first install peer from npm. </p><p><b>npm install peer</b></p><p>Now let's create NodeJs script. </p><p><b>const { PeerServer } = require('peer');</b></p><p><b>const peerServer = PeerServer({ port: 9000, path: '/server' });</b></p><p><b>peerServer.on('connection', (client) => { </b></p><p><b><span style="white-space: pre;"> </span>console.log(client);</b></p><p><b>});</b></p><p>That's is now you can run this script through terminal and it will run your server on 9000 port.</p><p>Now let's connect to server from our ReactJS component. </p><p>First lets install peerjs npm which is peer client. </p><p><b>npm install peerjs</b></p><p>We can connect to server in componentDidMount method and add some callbacks function.</p><p><b>import Peer from 'peerjs';</b></p><p><b>componentDidMount = () => {</b></p><p><b> this.peer = new Peer("USERNAME", {</b></p><p><b> host: 'localhost',</b></p><p><b> port: 9000,</b></p><p><b> path: '/server'</b></p><p><b> });</b></p><p> <b>this.peer.on("error", err => {</b></p><p><b> console.log("error: ", err)</b></p><p><b> })</b></p><p><b> this.peer.on("open", id => {</b></p><p><b> console.log(id)</b></p><p><b> })</b></p><p><b> this.peer.on("connection", (con) => {</b></p><p><b> console.log("connection opened");</b></p><p><b> con.on("data", i => {</b></p><p><b> console.log(i)</b></p><p><b> });</b></p><p><b> })</b></p><p><b>}</b></p><p>In above code first function is the error callback function. Second once is when peer connection is opened. Third one is when you receive connection from some other peer and get some data. </p><p>Now let's take an example of how you can connect to other peer and send data. </p><p><b>const conn = this.peer.connect('REMOTE_PEER');</b></p><p><b>conn.on('open', () => {</b></p><p><b> conn.send('DATA');</b></p><p><b>});</b></p><p>In above code we are connecting to some remote peer and sending some data to it.</p><p>Please note here peer to peer data goes through ICE server which you can setup and assign when you create peer server or else it will use PeerCloud server by default. For the development purpose that's ok but for the production you should create your on TURN or STUN server.</p><p>Hope this helps you in setting up </p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-3359576371931322282021-06-26T18:13:00.001+05:302021-06-26T18:13:22.915+05:30Create Question And Answer NLP Model With Bert<p>Hello,</p><p>Recently I worked on POC for chatbot where I evaluated Question Answering with Bert. Here in this blog we will see how you can create Question, Answering with Bert.</p><p><b>What is Bert?</b></p><p>According to team, who developed Bert</p><p><b>BERT stands for Bidirectional Encoder Representations from Transformers. It is designed to pre-train deep bidirectional representations from unlabelled text by jointly conditioning on both left and right context. As a result, the pre-trained BERT model can be fine-tuned with just one additional output layer to create state-of-the-art models for a wide range of NLP tasks.”</b></p><p>Bert is pertained on massive dataset and large corpus of unlabelled text. That's the hidden power of Bert as it uses knowledge gained from pre-training and apply it to dataset given. </p><p>For this POC we used HuggingFace's transformers. So first you have to install transformers. Using this model you can get advantage of pre trained data and then you can pass your reference text to it and this model will try to find answers from it.</p><p><b>pip install transformers</b></p><p>or </p><p><b>pip3 install transformers</b></p><p>Because this models are very big and it takes time to load and download. Let's first save it. Create model.py file and add following code.</p><p><b>from transformers import BertForQuestionAnswering</b></p><p><b>from transformers import BertTokenizer</b></p><p><b></b></p><p><b>BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad').save_pretrained('./trainedModel')</b></p><p><b>BertTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad').save_pretrained('./trainedModel')</b></p><p>Now execute it with python command. It will create trainedModel directory and save model there with all required files. Now we can load this pertained saved model.</p><p><b>from transformers import BertForQuestionAnswering</b></p><p><b>from transformers import BertTokenizer</b></p><p><b>import torch</b></p><p><b>bertPreTrainedModel = BertForQuestionAnswering.from_pretrained('./trainedModel')</b></p><p><b>tokenizer = BertTokenizer.from_pretrained('./trainedModel')</b></p><p><b>encoded = tokenizer.encode('YOUR_QUESTION', 'YOUR_REFERENCE_TEXT')</b></p><p><b>tokens = tokenizer.convert_ids_to_tokens(encoded)</b></p><p><b>sepLocation = encoded.index(tokenizer.sep_token_id)</b></p><p><b>first_seg_len, second_seg_len = sepLocation + 1, len(encoded) - (sepLocation + 1)</b></p><p></p><p><b>seg_embedding = [0] * first_seg_len + [1] * second_seg_len</b></p><p><b>modelScores = bertPreTrainedModel(torch.tensor([encoded]), token_type_ids=torch.tensor([seg_embedding]))</b></p><p><b>ans_start_loc, ans_end_loc = torch.argmax(modelScores[0]), torch.argmax(modelScores[len(modelScores)-1])</b></p><p><b>result = ' '.join(tokens[ans_start_loc:ans_end_loc + 1])</b></p><p><b>result = result.replace(' ##', '')</b></p><p>Here you will get your answer in result. This way you can develop your model using BERT and transformers.</p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-78405387580899104822021-06-26T17:33:00.003+05:302021-06-26T17:33:31.807+05:30How to Create Custom Theme for UI using Grommet V2<p> Hello,</p><p>In this blog we will understand how you can create custom theme for your using Grommet V2 in your React app.</p><p>Using Grommet v2, you can leverage the theme capabilities and define a customTheme as a JS object with your desired colors, margin padding etc. Let's see how we can do this. </p><p>First define your custom theme as JS object. As you can see we have defined some existing grommet color like background, brand. Also we have defined our own color like custom-1, custom-2 etc and then used it in button. </p><p><b>const customTheme = {</b></p><p><b> global: {</b></p><p><b> colors: {</b></p><p><b> background: "#fff",</b></p><p><b> brand: "#000",</b></p><p><b> "custom-1": "#aaaaaa",</b></p><p><b> "custom-2": "#bbbbbb",</b></p><p><b> "custom-3": "#444444"</b></p><p><b> }</b></p><p><b> },</b></p><p><b> button: {</b></p><p><b> default: {</b></p><p><b> background: "brand",</b></p><p><b> color: "white"</b></p><p><b> },</b></p><p><b> primary: {</b></p><p><b> background: "custom-1",</b></p><p><b> color: "white"</b></p><p><b> },</b></p><p><b> secondary: {</b></p><p><b> background: "custom-3",</b></p><p><b> color: "dark-2"</b></p><p><b> }</b></p><p><b> }</b></p><p><b>}</b></p><p>For more information on theme customisation and JSON structure you can visit <a href="https://v2.grommet.io/grommet" target="_blank">Official Grommet site</a></p><p>Now you can apply this theme to your application as below.</p><p><b>import { Grommet, Box } from 'grommet';</b></p><p><b>const DemoGrommet = () => (</b></p><p><b> <Grommet theme={customTheme}></b></p><p><b> <Box background="custom-1" ></b></p><p><b> </Box></b></p><p><b> </Grommet></b></p><p><b>);</b></p><p><b>export default DemoGrommet;</b></p><div>In case you want to keep default values of Grommet theme and want to override only few things with your theme, you can use deepMerge function provided by grommet v2 utils. </div><div><br /></div><div><div><b>import { deepMerge } from 'grommet/utils';</b></div><div><br /></div></div><div><div><b>import { generate } from 'grommet/themes/base';</b></div><div><b><br /></b></div><div><div><b>const mergedTheme = deepMerge(generate(16), </b><b>customTheme</b><b>);</b></div><div><b><br /></b></div><div>Here generate function generates default theme with 16 pixel font size and then it merge it with your custom theme and provide you updated theme.</div></div></div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-59499083196957610482021-06-26T16:32:00.000+05:302021-06-26T16:32:11.881+05:30How to Get Video Thumbnails with Javascript<p>Hello,</p><p>In this blog we will see how you can generate thumbnail of video using JavaScript. Let's assume you have file upload in your HTML as following.</p><p><b><input type="file" id="uploadVideo" accept="video/mp4" /></b></p><div>Now let's add an onChange listener for this.</div><div><br /></div><div><div><b>document.querySelector("#uploadVideo").addEventListener('change', function() {</b></div><div><b><span> var inputFile = </span>document.querySelector("#</b><b>uploadVideo</b><b>").files[0];</b></div><div><b> </b><b>getVideoThumbnail(inputFile)</b></div><div><b>});</b></div></div><div><b><br /></b></div><div>Now when you upload video it will call this function and you can access this video by using files property. Now we got the file. First step we will do is get blob URL of video so we can access metadata of video. Check below function. </div><div><br /></div><div>Here first what we are doing is creating video element and assigning blob URL to it from input file using URL.createObjectURL method.</div><div><br /></div><div>Then we have added event listener for meta data. This is necessary as we can't get video data till them time meta data is loaded. </div><div><br /></div><div>Then we seek video to 0.0 second. You can add your own time here in case if you need. Then we have added seeked listener. By this time we have video data is available. Now we are using canvas to drawImage from video frame data.</div><div><br /></div><div>Then using toDataURL method we get the base64Data. Here 0.60 is value of quality. If you don't want to compromise quality of image then you can pass 1 here. </div><div><br /></div><div><div><b>function getVideoThumbnail(</b><b>inputFile</b><b>) {</b></div><div><b> try {</b></div><div><b> let video = document.createElement('video');</b></div><div><b> let blobSrc = URL.createObjectURL(</b><b>inputFile</b><b>);</b></div><div><b> video.setAttribute('src', blobSrc);</b></div><div><b> video.addEventListener('error', () => {</b></div><div><b> console.log("Error")</b></div><div><b> });</b></div><div><b> video.addEventListener('loadedmetadata', () => {</b></div><div><b> setTimeout(() => {</b></div><div><b> video.currentTime = 0.0;</b></div><div><b> }, 200);</b></div><div><b> video.addEventListener('seeked', () => {</b></div><div><b> let canvas = document.createElement('canvas');</b></div><div><b> video.pause();</b></div><div><b> canvas.width = 400</b></div><div><b> canvas.height = 400;</b></div><div><b> let ctx = canvas.getContext('2d');</b></div><div><b> ctx.drawImage(video, 0, 0, canvas.width, canvas.height);</b></div><div><b> var base64Data = ctx.canvas.toDataURL(</b></div><div><b> 'image/png',</b></div><div><b> 0.60</b></div><div><b> );</b></div><div><b><span> </span><span> </span><span> // SET this data in SRC of image tag or you can add your own logic.</span><br /></b></div><div><b> });</b></div><div><b> });</b></div><div><b><span> </span></b><b> video.load();</b></div><div><b> } catch (err) {</b></div><div><b> </b></div><div><b> }</b></div><div><b>}</b></div></div><div><br /></div><div>Hope this helps you.</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-11543966260723002332021-03-19T18:29:00.004+05:302021-03-19T18:29:53.063+05:30How to solve proxy_fcgi:error AH01071: Got error 'Unable to open primary script<p> Hello,</p><p>Recently I got stuck with strange bug on centOS server. After I updated document root for my primary domain which has Laravel App installed. </p><p>When we try to access app through domain, we got following error. </p><p><b><span style="font-size: medium;">No input file specified.</span></b></p><p>I initially thought it's the permission issue on .htaccess issue. Tried changing permissions and adding some rewrite rules but it didn't work. When I checked apache error logs. I got following error. </p><p><b><span style="font-size: large;">proxy_fcgi:error AH01071: Got error 'Unable to open primary script</span></b></p><p>I had no idea how to solve this error. So tried few things like</p><p></p><ul style="text-align: left;"><li>Restart apache</li><li>Restart php-fpm</li><li>Restart VPS</li><li>Removed and added account few times.</li><li>Disabling php-fpm</li></ul><div>But nothing worked. I spent almost entire night in solving this issue but no luck. But finally I was able to solve the issue by following steps. It was actually the issue with php fpm, as it was not able to find out root folder for the domain. So here is what you have to do. </div><div><br /></div><div>First go to userdata directory </div><div><br /></div><div>/var/cpanel/userdata/<USERNAME></div><div><br /></div><div>Here you will find one file. </div><div><br /></div><div>yourdomain.com.php-fpm.yaml</div><div><br /></div><div>Open this file with nano or vim editor and add following line at the end of it. </div><div><br /></div><div><b>php_admin_value_doc_root: { name: 'php_admin_value[doc_root]', value: /home/<USERNAME>/public_html/<DOCUMENT_ROOT> }</b></div><div><br /></div><div>Save the file and then execute following commands one by one.</div><div><br /></div><div><b>/scripts/php_fpm_config --rebuild </b></div><div><b><br /></b></div><div><b>/scripts/restartsrv_apache_php_fpm </b></div><div><b><br /></b></div><div><b>/scripts/restartsrv_httpd</b></div><div><br /></div><div>This will rebuild php fpm config and restart php fpm service for apache. Now in the same folder open </div><div><br /></div><div>YOURDOMAIN.com </div><p></p><div>YOURDOMAIN.com_SSL</div><div><br /></div><div>Change document root here as well and run following commands.</div><div><br /></div><div><b>/scripts/rebuildhttpdconf </b></div><div><b><br /></b></div><div><b>/scripts/restartsrv_httpd</b></div><div><br /></div><div>This will rebuild apache config file and restart apache. </div><div><br /></div><div>This is it and now if you visit your domain, you will not have the issue of file missing. </div><div><br /></div><div>Hope this saves your time</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com1tag:blogger.com,1999:blog-7442072150765022610.post-10977931301461832272020-12-09T17:48:00.004+05:302020-12-09T17:48:41.960+05:30Restore MySql Database From Just frm and idb File<p>Hello,</p><p>Few days back, I encountered a situation where we needed to restore MySql Database but we only had frm and idb file. Didn't have .sql file or log file from MySql server which is very much needed when you want to restore. So here in this blog I am going to explain how you can still restore MySql Database from only frm and idb file.</p><p>First you will need a tool called dbsake which you can install with following command.</p><p><span style="font-family: Menlo; font-size: 36px; font-variant-ligatures: no-common-ligatures;">curl -s http://get.dbsake.net > dbsake</span></p><p>Once installed, run following command to check if it's installed properly or not. </p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">chmod u+x dbsake</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">./dbsake --version</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;">If it shows version and all, it's installed. Now first by using this tool we will get schema of table from frm file. Run following command. </span></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;"><br /></span></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">./dbsake frmdump /PATH_TO_FRM/file.frm</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span style="font-family: Times; font-size: medium;">It will give you create table schema like this.</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span style="font-family: Times; font-size: medium;"><br /></span></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>CREATE TABLE `table_name` (</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column1` int(11) NOT NULL AUTO_INCREMENT,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column2` varchar(255) DEFAULT NULL,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column3` varchar(255) DEFAULT NULL,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> PRIMARY KEY (`column1`)</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>) ENGINE=InnoDB DEFAULT CHARSET=utf8;</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Copy it and run it in your sql editor. If you are migrating it from MySql 5 to 6 you may want to add ROW_FORMAT</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>CREATE TABLE `table_name` (</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column1` int(11) NOT NULL AUTO_INCREMENT,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column2` varchar(255) DEFAULT NULL,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> `column3` varchar(255) DEFAULT NULL,</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b> PRIMARY KEY (`column1`)</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=compact;</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Now it will create table. It's time to load data into it. </p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">First we will delete the table space which is idb file created. Run following command.</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>ALTER TABLE table_name DISCARD TABLESPACE</b></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Now copy the old idb file and replace the existing one in your MySql server.</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;">Now attach table space again.</p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><br /></p><p class="p1" style="font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><b>ALTER TABLE table_name IMPORT TABLESPACE</b></p><div><br /></div><div>That's it and now if you browse the data in table, you can see all your old rows. </div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-67448905109810789512020-09-29T11:17:00.002+05:302021-02-13T16:13:05.244+05:30MySql Export / Import Large Database<p>Hello,</p><p>In this blog I am going to explain a trick which I recently used for Export / Import large database. </p><p>Let me first explain the issue I faced. The database was over 250 MB. I was using MySql WorkBench to export in single self contained file. But it was breaking in between as some tables were really huge. </p><p>So here is what I did. First in MySql WorkBench, in stead of exporting it to self contained single file, export it to Dump project folder. Here it will create sql file for each table in the folder. So in my case it created approximately 180 sql files. </p><p>Now open terminal and go to that folder. First step here is we will concat all those files and make a single file.</p><p>Run the following command in terminal from folder where you have all the sql files.</p><p><br /></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">cat *.sql<span class="Apple-converted-space"> </span>> .single_file.sql</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;">Above command will concat all the files into one file and create that file in same folder. Now we will use this file to import into our database.</span></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;"><br /></span></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;">/Applications/MAMP/Library/bin/mysql -u DB_USER -p DB < .single_file.sql</span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-family: Menlo; font-size: 36px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: Times; font-size: medium; font-variant-ligatures: normal;">That's it. With this trick you can Import / Export large database. Please note that, for this you should have terminal access to your MySql server.</span></span></p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-25105068031436413132020-09-07T11:41:00.002+05:302020-09-07T11:41:40.816+05:30Connect to Web Socket From Your Android App using OkHttp<p>Hello,</p><p>In this blog I am going to explain how you can connect with Web Socket from your Android App using OkHttp. This will be useful when you want to send some data real time from your Android app to Web app. </p><p>First add following line in your build.gradle file dependencies. </p><p><b>implementation 'com.squareup.okhttp3:okhttp:3.11.0'</b></p><p>Now let the gradle build and sync. Next we will make a class which extends WebSocketListener from OkHttp3 and a new class and name it MyWebSocketListener.java and add following code to it. </p><p><b>import okhttp3.Response;</b></p><p><b>import okhttp3.WebSocket;</b></p><p><b>import okhttp3.WebSocketListener;</b></p><p><b>import okio.ByteString;</b></p><p><b>public final class MyWebSocketListener extends WebSocketListener {</b></p><p><b> private static final int NORMAL_CLOSURE_STATUS = 5000;</b></p><p><b> public MyWebSocketListener() { </b></p><p><b> }</b></p><p><b> @Override</b></p><p><b> public void onOpen(WebSocket webSocket, Response response) {</b></p><p><b> webSocket.close(NORMAL_CLOSURE_STATUS, "Exit");</b></p><p><b> }</b></p><p><b> @Override</b></p><p><b> public void onMessage(WebSocket webSocket, String text) {</b></p><p><b> //String Meesage received</b></p><p><b> }</b></p><p><b> @Override</b></p><p><b> public void onMessage(WebSocket webSocket, ByteString bytes) {</b></p><p><b> //Meesage received in form of binary data</b></p><p><b> }</b></p><p><b> @Override</b></p><p><b> public void onClosing(WebSocket webSocket, int code, String reason) {</b></p><p><b> webSocket.close(NORMAL_CLOSURE_STATUS, null);</b></p><p><b> //Closing socket</b></p><p><b> }</b></p><p><b> @Override</b></p><p><b> public void onFailure(WebSocket webSocket, Throwable t, Response response) {</b></p><p><b> t.printStackTrace();</b></p><p><b> }</b></p><p><b>}</b></p><p>Now we have listener created. Let's create client and attach it to Web Socket and Listener.</p><p><b>val listener = MyWebSocketListener()</b></p><p><b>val webSocket = OkHttpClient.Builder().build().newWebSocket(request, listener)</b></p><p><br /></p><p>That's it, now you can use this instance to send or receive message.</p>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-43113904032930447662020-09-05T12:55:00.002+05:302020-09-05T12:55:16.917+05:30Create Secure Web Socket (WSS) with Ratchet PHP <p>Hello,</p><p>Recently I was working on PHP project where we I was create secure web socket which is accessible with wss:// protocol. For this I struggled for couple of hours so here in blog I am going to explain how to do that so it can save your time. </p><p>Earlier version was not supporting WSS but later it introduced React socket server which allows SSL connection. So here are steps you need to follow. </p><p>First add all the required classed in your php file.</p><p><br /></p><p><b>use Ratchet\Server\IoServer;</b></p><p><b>use Ratchet\Http\HttpServer;</b></p><p><b>use Ratchet\WebSocket\WsServer;</b></p><p><b>use MyApp\Socket;</b></p><div><br /></div><div>In above example Socket is my class file which has all listeners. After this add auto load file.</div><div><br /></div><div><div><b>require dirname( __FILE__ ) . '/vendor/autoload.php';</b></div></div><div><br /></div><div>Next we will create our socket app. </div><div><br /></div><div><div><b>$app = new \Ratchet\Http\HttpServer(</b></div><div><b> new \Ratchet\WebSocket\WsServer(</b></div><div><b> new \MyApp\Socket()</b></div><div><b> )</b></div><div><b>);</b></div></div><div><b><br /></b></div><div>Now next step is to create React Secure server.</div><div><br /></div><div><div><b>$loop = \React\EventLoop\Factory::create();</b></div><div><b>$webSock = new \React\Socket\Server('0.0.0.0:8080', $loop);</b></div></div><div><b><br /></b></div><div>We are using 0.0.0.0 so this socket can be connected from anywhere. </div><div><br /></div><div>Now lets create secure server by adding path to certificate and key</div><div><br /></div><div><b>$webSock = new \React\Socket\SecureServer($webSock, $loop, [</b></div><div><b><span> </span>'local_cert' => 'CRT_PATH', </b></div><div><b><span> </span>'local_pk'=> 'KEY_PATH', </b></div><div><b><span> </span>'allow_self_signed' => true, </b></div><div><b><span> </span>'verify_peer' => false</b></div><div><b>]);</b></div><div><b><br /></b></div><div>Now finally we will run our server.</div><div><br /></div><div><div><b>$webSock = new \Ratchet\Server\IoServer($app, $webSock, $loop);</b></div><div><b>$webSock->run();</b></div></div><div><b><br /></b></div><div>That's it. It will start your server to which you can connect with WSS protocol. To test you can use WebSocket ECHO test.</div><div><br /></div><div><a href="https://www.websocket.org/echo.html">https://www.websocket.org/echo.html</a></div><div><br /></div><div>Hope this helps you.</div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-760046636739239132020-08-20T16:04:00.001+05:302020-08-20T16:04:07.450+05:30AWS PHP SDK - Create an Entry in Route53 - Laravel<p> Hello,</p><p>In this blog I will explain you how to you can create an entry in Route53 hosted zone using AWS PHP SDK. Solution I mentioned here is particularly for Laravel app, but you can still use it in any of the PHP project. </p><p>This solution is pretty much useful when you want to make a dynamic entry in your hosted. For example a dynamic sub domain creation. </p><p>First of all your need install couple of packages using composer. Following are the packages. </p><p><b>"aws/aws-sdk-php": "^3.148",</b></p><p><b>"aws/aws-sdk-php-laravel": "~3.0",</b></p><p>You can either install it by adding it in composer.json file or you can install it using composer require. </p><p>Once the installation is done, follow the steps mentioned in below URL. </p><p><span style="font-size: x-large;"><a href="https://github.com/aws/aws-sdk-php-laravel">https://github.com/aws/aws-sdk-php-laravel</a></span></p><p>Once installation is done. You need to add following keys in your env file.</p><p>AWS_ACCESS_KEY_ID</p><p>AWS_SECRET_ACCESS_KEY</p><p>AWS_REGION (default = us-east-1)</p><p>Set the values in above keys from your AWS account. That's it your AWS SDK is ready. Now add following line your controller where you want to have logic for adding value in Route53</p><p>use Aws\Route53\Route53Client;</p><p>use Aws\Common\Credentials\Credentials;</p><p>Now next step is to create a client</p><p>$client = Route53Client::factory(array(</p><p> 'credentials' => config('aws.credentials'),</p><p> 'region' => config('aws.region'),</p><p> 'version' => config('aws.version'),</p><p>)); </p><p>After client is created we will use changeResourceRecordSets to create an entry.</p><p>$result = $client->changeResourceRecordSets(array(</p><p> // HostedZoneId is required</p><p> 'HostedZoneId' => 'YOUR_HOSTED_ZONE_ID',</p><p> // ChangeBatch is required</p><p> 'ChangeBatch' => array(</p><p> 'Comment' => 'string',</p><p> // Changes is required</p><p> 'Changes' => array(</p><p> array(</p><p> // Action is required</p><p> 'Action' => 'CREATE',</p><p> // ResourceRecordSet is required</p><p> 'ResourceRecordSet' => array(</p><p> // Name is required</p><p> 'Name' => 'YOUR_VALUE',</p><p> // Type is required</p><p> 'Type' => 'CNAME', //A, CANME</p><p> 'TTL' => 600,</p><p> 'ResourceRecords' => array(</p><p> array(</p><p> // Value is required</p><p> 'Value' => 'YOUR_VALUE', //IP address or load balancer.</p><p> ),</p><p> ),</p><p> ),</p><p> ),</p><p> ),</p><p> ),</p><p> ));</p><div>That's it and it will create an entry in Route53 hosted zone. </div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-72020626032905000572020-08-04T15:45:00.005+05:302020-08-04T15:45:59.774+05:30Android Build Error - The Crashlytics build ID is missingHello,<div><br /></div><div>Recently I faced a very strange issue in one of my android app. We were using Fabric IO for crash analytics earlier in the app and since now it's already merged with Firebase Analytics. we need to update the app. </div><div><br /></div><div>I removed Firebase maven repository and removed all plugins from build gradle file and removed Fabric code from everywhere. And build was successful. After that I followed all the instructions on getting started page of Firebase and crash analytics and build was successful. And then problem started. Once we run the app, it crashes and shows following error in Logcat. </div><div><br /></div><div>"<b>The Crashlytics build ID is missing. This occurs when Crashlytics tooling is absent from your app's build configuration. Please review Crashlytics onboarding instructions and ensure you have a valid Crashlytics account</b>" </div><div><br /></div><div>Now it seems there is an issue with Firebase crash analytics account so I regenerated the google service json file add updated in project. But it didn't help. </div><div><br /></div><div>Searched on Google, answers suggest to put back Fabric plugin again in gradle file. Which does not make any sense to me. Since Fabric is out dated, why do we need to add it again. </div><div><br /></div><div>Finally after 2 days I was able to solve the problem. Here is the solution</div><div><br /></div><div><div class="css-1dbjc4n r-a1ub67" style="-webkit-box-align: stretch; -webkit-box-direction: normal; -webkit-box-orient: vertical; align-items: stretch; background-color: white; border: 0px solid black; box-sizing: border-box; display: flex; flex-basis: auto; flex-direction: column; flex-shrink: 0; margin: 11px 0px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; z-index: 0;"><div class="css-901oao r-hkyrab r-1qd0xha r-1x35g6 r-16dba41 r-ad9z0x r-bcqeeo r-bnwqim r-qvutc0" dir="auto" lang="en" style="border: 0px solid black; box-sizing: border-box; color: #14171a; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: 24px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; position: relative; white-space: pre-wrap;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; color: inherit; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: inherit;">Remove google service json file. Use Firebase assistant and connect with your account again. Select the project and it again generate google service json file. Keep link to fabric io repository in top level gradle file.</span></div><div class="css-901oao r-hkyrab r-1qd0xha r-1x35g6 r-16dba41 r-ad9z0x r-bcqeeo r-bnwqim r-qvutc0" dir="auto" lang="en" style="border: 0px solid black; box-sizing: border-box; color: #14171a; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: 24px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; position: relative; white-space: pre-wrap;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; color: inherit; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: inherit;"><br /></span></div><div class="css-901oao r-hkyrab r-1qd0xha r-1x35g6 r-16dba41 r-ad9z0x r-bcqeeo r-bnwqim r-qvutc0" dir="auto" lang="en" style="border: 0px solid black; box-sizing: border-box; display: inline; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; position: relative;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; display: inline; font-size: 24px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: pre-wrap;"><font color="#14171a" face="system-ui, -apple-system, system-ui, Segoe UI, Roboto, Ubuntu, Helvetica Neue, sans-serif">maven {
url 'https://maven.fabric.io/public'
}</font></span></div><div class="css-901oao r-hkyrab r-1qd0xha r-1x35g6 r-16dba41 r-ad9z0x r-bcqeeo r-bnwqim r-qvutc0" dir="auto" lang="en" style="border: 0px solid black; box-sizing: border-box; display: inline; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; position: relative;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; display: inline; font-size: 24px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: pre-wrap;"><font color="#14171a" face="system-ui, -apple-system, system-ui, Segoe UI, Roboto, Ubuntu, Helvetica Neue, sans-serif"><br /></font></span></div><div style="font-size: 16px;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; color: inherit; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: inherit;"><span style="font-family: Times; font-size: medium;">I don't know how it worked but it works and I really don't know the reason of why it didn't work and why it started working after above solution. But it does solve the problem. </span></span></div><div style="font-size: 16px;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; color: inherit; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: inherit;"><span style="font-family: Times; font-size: medium;"><br /></span></span></div><div style="font-size: 16px;"><span class="css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0" style="border: 0px solid black; box-sizing: border-box; color: inherit; display: inline; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: 1.3125; margin: 0px; min-width: 0px; overflow-wrap: break-word; padding: 0px; white-space: inherit;"><span style="font-family: Times; font-size: medium;">If anyone who is reading this blog, knows the reason please put in comment. </span></span></div></div><div class="css-1dbjc4n r-1r5su4o" style="-webkit-box-align: stretch; -webkit-box-direction: normal; -webkit-box-orient: vertical; align-items: stretch; background-color: white; border: 0px solid black; box-sizing: border-box; display: flex; flex-basis: auto; flex-direction: column; flex-shrink: 0; font-size: 16px; margin: 16px 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; z-index: 0;"><div class="css-1dbjc4n r-1awozwy r-18u37iz r-1wtj0ep" style="-webkit-box-align: center; -webkit-box-direction: normal; -webkit-box-orient: horizontal; -webkit-box-pack: justify; align-items: center; border: 0px solid black; box-sizing: border-box; display: flex; flex-basis: auto; flex-direction: row; flex-shrink: 0; justify-content: space-between; margin: 0px; min-height: 0px; min-width: 0px; padding: 0px; position: relative; z-index: 0;"></div></div></div>Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com1tag:blogger.com,1999:blog-7442072150765022610.post-32514911421220129042020-03-22T11:36:00.000+05:302020-03-22T11:36:57.433+05:30Angular 7 App ng build Works But ng build --prod Gives Error<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
Recently I was trying to generate production build of one of our older Angular app which was built on Angular 6 and later upgraded to Angular 7. When we run ng build it works fine but when we run ng build --prod it gives so many errors.<br />
<br />
Here in this blog I am going to explain what are those errors and how I solved it.<br />
<br />
<b>Problem 1 : Strict Parameter checking for function.</b><br />
<br />
There were few events and handler defined in the app where there were parameter mismatch. For example in html file we have following event.<br />
<br />
<componentName (event)="eventHandler($event)"></componentName ><br />
<br />
And in component TS file event handler was defined like this<br />
<br />
eventHandler() {<br />
}<br />
<br />
As you can see from html file it was passing $event param but on handler param was not mentioned. So make sure that your function signature and function declaration matches.<br />
<br />
<b>Problem 2 : Duplicate Declaration of Components</b><br />
<b><br /></b>
By mistake we have duplicate declaration of components in both App module and and other child modules of the app. Make sure you either declare all your components to app module or if you are defining it into sub module then make sure you remove it from app module.<br />
<br />
<b>Problem 3 : Cannot read property 'moduleType' of undefined</b><br />
<b><br /></b>
When you face above issue please check your app module by mistake you may have defined following line twice in your app module.<br />
<br />
platformBrowserDynamic().bootstrapModule(AppModule);<br />
<br />
It's like you are trying to bootstrap your Angular app twice and it gives above error. So try to avoid it.<br />
<br />
<b>Problem 4 : Enable IVY</b><br />
<b><br /></b>
In Angular 7 by default IVY is disabled hence even if you generate production build you app size it bit large. To enable IVY add following line to your tsconfig.json file.<br />
<br />
"angularCompilerOptions": {<br />
"enableIvy": true<br />
}<br />
<div>
<b><br /></b></div>
<div>
Hope this blog post helps you.</div>
</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-18420070736430731872020-03-22T11:12:00.000+05:302020-03-22T11:13:40.650+05:30Laravel App Connect and Emit to Socket.io<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
Recently in one of the project I was working on we have socket.io server created using NodeJS and there were couple of Angular applications and android applications connects with it. However there was a requirement to connect with socket from Laravel app and emit the event.<br />
<br />
Actually there was a form in Laravel app on submit of Form we have to notify the socket and socket further notify all the clients connected to it. In this blog I am going to mention how we solved this.<br />
<br />
We all know Laravel by default comes with integration of Pusher we could have used it. But since Socket.io is free so we consider to use Socket.io.<br />
<br />
Let's go step by step and understand how to connect with Socket.io<br />
<br />
Step 1<br />
<br />
Create new folder socket in your app directory of Laravel app.<br />
<br />
Step 2<br />
<br />
Copy following class in to app/Socket folder and rename it to SocketIO.php<br />
<br />
<a href="https://github.com/psinetron/PHP_SocketIO_Client">https://github.com/psinetron/PHP_SocketIO_Client</a><br />
<br />
There are many PHP socket IO client is available but we used above one. You can choose either one of your choice.<br />
<br />
Step 3<br />
<br />
Connect and emit to socket. In your controller file where you want to emit the event. Add following code.<br />
<br />
$socketIO = new SocketIO();<br />
$returnValue = $socketIO->send('YOUR_URL', YOUR_PORT, 'YOUR_EVENT',json_encode(YOUR_PHP_ARRAY))<br />
<br />
For this add following line to top of your controller.<br />
<br />
use App\socket\SocketIO;<br />
<br />
That's it and now you can connect with socket and emit event to it.</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-4600824050284757822020-03-22T10:56:00.000+05:302020-03-22T10:57:29.665+05:30Socket.io Not Working on Android 9 (API 28)<div dir="ltr" style="text-align: left;" trbidi="on">
Hi,<br />
<br />
Recently in one of the project we faced a situation where we have used socket.io on backend and Android app connects to it. Socket.io was using http protocol for testing. It worked fine in older android versions but faced an issue in Android 9 and above where socket was connected but emit was not getting on server.<br />
<br />
After couple of hours struggle finally found the problem. The problem was socket io was using http protocol and it's clearText HTTP request and it is banned in recent android version considering security reasons.<br />
<br />
In earlier android version by default clearText is set as true but in later version default value is false. That means android components like HTTP and FTP and classes DownloadManager, and MediaPlayer can not use HTTP.<br />
<br />
To over come this issue and allow socket to connect with HTTP protocol you have to allow clearText traffic on app level and for that you have to add following attribute in Application tag of your AndroidManifest.xml<br />
<br />
<application<br />
android:usesCleartextTraffic="true"><br />
.....<br />
</application><br />
<br />
Once you add this to your manifest file, your socket emit will start working and you can still use HTTP with your socket.<br />
<br />
Please note that since it was testing app we used HTTP based socket. However in production you should always use HTTPs protocol.<br />
<br />
Hope this helps you.<br />
<br />
<br /></div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-30974551518463642312019-08-21T09:49:00.000+05:302019-08-21T09:49:08.473+05:30NodeJs MySQL Observer<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
In this blog we are going to learn how to use NodeJs to observe changes in MySql databases. This is useful when you want to track MySQL changes and based on that want to send some events to frontends or want to do any other actions.<br />
<br />
For this first of all you have to enable binary logging in you database. Binary logging is very much useful for real time MySQL replication. In Amazon RDS, it's by default available and you can switch on it from configurations. For your local database if you are using MAMP, you can do following trick.<br />
<br />
Create a file with name my.cnf and add following content to it.<br />
<br />
[mysqld]<br />
server-id = 1<br />
default-storage-engine = InnoDB<br />
log-bin=bin.log<br />
log-bin-index=bin-log.index<br />
max_binlog_size=100M<br />
expire_logs_days = 10<br />
binlog_format=row<br />
socket=mysql.sock<br />
<br />
Add this file to conf folder of your MAMP directory and restart MySQL server. This will enable binary logging in your database.<br />
<br />
Now to observe this changes we use npm package called zongji . Install it with NPM.<br />
<br />
Add following code to your NodeJs script.<br />
<br />
var ZongJi = require('zongji');<br />
var _underScore = require('underscore');<br />
<div>
<br /></div>
<div>
<div>
var zongji = new ZongJi({</div>
<div>
user : 'YOUR_USERNAME',</div>
<div>
password : "YOUR_PASSWORD",</div>
<div>
database: 'YOUR_DATABASE',</div>
<div>
socketPath : '/Applications/MAMP/tmp/mysql/mysql.sock'</div>
<div>
});</div>
</div>
<br />
Now add event on binlog.<br />
<br />
zongji.on('binlog', function(evt) {<br />
<div>
<br /></div>
<div>
});</div>
<div>
<br /></div>
<div>
This event is triggered whenever there is a change in any of your database tables.</div>
<div>
<br /></div>
<div>
Inside this event you can have logic of checking new rows, updates rows, deleted rows.</div>
<div>
zongji.on('binlog', function(evt) {</div>
<div>
<div>
if (evt.getEventName() === 'writerows' || evt.getEventName() === 'updaterows' || evt.getEventName() === 'deleterows') {</div>
<div>
<span style="white-space: pre;"> </span>var database = evt.tableMap[evt.tableId].parentSchema; </div>
<div>
var table = evt.tableMap[evt.tableId].tableName; </div>
<div>
var columns = evt.tableMap[evt.tableId].columns; </div>
</div>
_underScore.each(evt.rows, function(row) {<br />
});<br />
}<br />
});<br />
<br />
At last start the process and pass the events you want to watch.<br />
zongji.start({<br />
includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows']<br />
});</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-34610756203961894252019-08-20T09:08:00.000+05:302019-08-20T09:08:29.043+05:30ReactJs Material UI Table Infinite Scroll<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
Recently in one of my ReactJs project, I faced a challenge in implementing infinite scroll in Material UI table. In this blog I am going to mention trick I have used.<br />
<br />
First of all I was really surprised to see that Material UI table does not have infinite scroll function out of the box. It's very much needed. Sometimes something can not be achieved with frameworks, can be achieved via basics of JavaScript. In this I have done something similar.<br />
<br />
I tried adding on scroll events on Table, Table Body but it didn't work. I also tried adding refs to body and then bind the Scroll event but that also did not work. After struggling for couple of hours, I finally decided to it with Pure JavaScript.<br />
<br />
<b>Step 1 : Wrap material UI table inside the container with fixed height and set overflow = scroll to container.</b><br />
<b><br /></b>
<b></b><br />
import styled from "styled-components";<br />
<b><br /></b>
export const Table = props => (<br />
<TableWrapper id={props.id}><br />
<MuiTable {...props}/><br />
</TableWrapper><br />
<br />
);<br />
<br />
const TableWrapper = styled.div`<br />
max-height: 500px;<br />
overflow: scroll;<br />
<br />
::-webkit-scrollbar {<br />
width: 3px;<br />
height: 3px;<br />
}<br />
`;<br />
<br />
As you can see I created a wrapper of table and set max height to it. You can make it dynamic as well depending on window height.<br />
<br />
<b>Step 2: Import Table to your component</b><br />
<b><br /></b>
import {<br />
Table<br />
<br />
} from './components/Table';<br />
<br />
return (<br />
<> <br />
<Table id={"tableID"}/><br />
</><br />
);<br />
<br />
<b>Step 3: Bind scroll event to wrapper</b><br />
<b><br /></b>
let me = this;<br />
document.getElementById('tableID').onscroll = function(event){<br />
if(this.scrollTop == (this.scrollHeight - this.clientHeight)){<br />
//User reached bottom of table after scroll<br />
//Logic to call web services to get next set of data<br />
}<br />
};<br />
<br />
Hope this helps you.</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-26688760863449952622019-08-19T08:15:00.000+05:302019-08-19T08:15:28.024+05:30Accessing Data From Redis Using NodeJs<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
When you are working with business applications, it's sometimes need to cache the data. At this point Redis can be very useful, it can be used as database or cache database. You can store any kind of data like strings, JSON objects etc. in Redis.<br />
<br />
Problem we face while working with NodeJs and Redis, get data operation from Redis is Asynchronous operations so it gives you callback and your code execution will continue. This may create a problem when you want to handle it in Synchronous way. For example you may have loops inside that you are trying to access data from Redis.<br />
<br />
In this blog I am going to explain how you can have Synchronous operations. In nutshell we got to promisify the redis module.<br />
<br />
There is a library called bluebird, that can be used for this. Lets go step by step.<br />
<br />
<b>Step 1</b><br />
<br />
Install bluebird and redis in your NodeJs app.<br />
<br />
npm install bluebird<br />
npm install redis<br />
<br />
<b>Step 2</b><br />
<br />
Import it in NodeJs app.<br />
<br />
var redis = require('redis');<br />
var bluebird = require("bluebird");<br />
<div>
<br /></div>
<div>
<b>Step 3</b></div>
<div>
<b><br /></b></div>
<div>
Promisify Redis.</div>
<div>
<br /></div>
<div>
<div>
bluebird.promisifyAll(redis.RedisClient.prototype);</div>
<div>
bluebird.promisifyAll(redis.Multi.prototype);</div>
</div>
<div>
<br /></div>
<div>
<b>Step 4</b></div>
<div>
<b><br /></b></div>
<div>
Connect to Redis client.</div>
<div>
<br /></div>
<div>
<div>
var client = redis.createClient();</div>
<div>
client.on('connect', function() {</div>
<div>
console.log('Redis client connected');</div>
<div>
});</div>
</div>
<div>
<br /></div>
<div>
<b>Step 5</b></div>
<div>
<b><br /></b></div>
<div>
Use Async version of get function to get data.</div>
<div>
<br /></div>
<div>
<div>
client.getAsync("MY_KEY").then(function(res) {</div>
<div>
//Access Data</div>
<div>
});</div>
</div>
<div>
<br /></div>
<div>
This is how you can have Sync operations with Redis. </div>
</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0tag:blogger.com,1999:blog-7442072150765022610.post-2537915041099676062019-08-15T15:43:00.001+05:302019-08-15T15:43:20.280+05:30ReactJs / Angular - Override Material UI Theme<div dir="ltr" style="text-align: left;" trbidi="on">
Hello,<br />
<br />
While working with React or Angular Applications we normally uses Material UI themes and components and it's great choice because it has nice set of themes and colors and ready to use components. That makes our life easy.<br />
<br />
One challenge we face is, in case if we want to change or override the theme. For example Material ui has dark blue theme. What if you want to change colors or dark blue theme with your own color. One option is you can declare the class with same name and give your own property. However the better solution is to use theme override. In this blog I am going to mention how to this.<br />
<br />
Please note the method I am going to mention here is specific to React application.<br />
<br />
First of all create theme.js file in your app and add following code to it.<br />
<br />
import React from "react";<br />
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles";<br />
import CssBaseline from "@material-ui/core/CssBaseline";<br />
import blueGrey from "@material-ui/core/colors/blueGrey";<br />
import lightBlue from "@material-ui/core/colors/lightBlue";<br />
import "typeface-roboto";<br />
<br />
import { ThemeProvider as ScThemeProvider } from "styled-components";<br />
<br />
export default props => (<br />
<ScThemeProvider theme={muiTheme}><br />
<MuiThemeProvider theme={muiTheme}><br />
<CssBaseline>{props.children}</CssBaseline><br />
</MuiThemeProvider><br />
</ScThemeProvider><br />
);<br />
<br />
const theme = {<br />
overrides: {<br />
<div>
<div>
},</div>
<div>
palette: {</div>
<div>
primary: { </div>
<div>
main: '#MAIN_COLOR' </div>
<div>
}, </div>
<div>
secondary: { </div>
<div>
main: '#SECONDARY_COLOR' </div>
<div>
},</div>
<div>
background: {</div>
<div>
default: '#BACKGROUND_COLOR'</div>
<div>
}</div>
<div>
},</div>
<div>
type: "dark"</div>
<div>
};</div>
</div>
<div>
<br /></div>
<div>
<div>
const muiTheme = createMuiTheme(theme);</div>
</div>
<div>
<br /></div>
<div>
Now here in overrides you can add code to override. For example if you want to change panel header. If you inspect html element you will find it has a class MuiPaper-root</div>
<div>
<br /></div>
<div>
Here is how you can override base CSS of it.</div>
<div>
<br /></div>
<div>
<div>
overrides: {</div>
<div>
MuiPaper: {</div>
<div>
root: {</div>
<div>
background: '#YOUR_COLOR'</div>
<div>
},</div>
<div>
rounded: {</div>
<div>
background: '#YOUR_COLOR'</div>
<div>
}</div>
<div>
}</div>
</div>
<div>
<br /></div>
<div>
Same way for any other components you can do it. Inspect the HTML structure, find out Class Name and override it.</div>
</div>
Hiren Davehttp://www.blogger.com/profile/03332234242233370508noreply@blogger.com0