Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Sunday, January 17, 2021

how to quickly fix "future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed "javascript:void(0)"

 when we implement a click event to trigger api call or dispatch an action in redux, we will like to use this simple syntax to handle it.

<a href="javascript:void(0)" onClick={clearFilter}>all posts</a>

we will see the following warming in the development tool windows


since React 16.9 update had deprecate the JavaScript URL, you can check out this link for more information

https://reactjs.org/blog/2019/08/08/react-v16.9.0.html

but the work around is quiet simple. we can fix it withe code below.

<a href="#" onClick={ev => {
            ev.preventDefault();
           clearFilter
            return false; // old browsers, may not be needed
            }}>all posts</a>


 








Saturday, December 5, 2020

use This keyword with Arrow Function in Javascript implementation

 when we write JavaScript function with Arrow to eliminate the function key, we must be extra caution, since THIS keyword object reference will be determine during the runtime, if the function is in the global scope, then THIS will point to the window object. if the function is pointing within the object, then THIS will only point to the object itself.

here is a simple example.

print: (delay=3000)=> {
    setTimeout(() => {
    console.log(this === window)
    }, delay)
}

the output is true. since THIS is execute with under the global scope.


after I change the Arrow function to a regular function, then  THIS key is reference to the object level

function print(delay=3000){
    setTimeout(() => {
    console.log(this === window)
    }, delay)
}

though arrow function is very handy in the javascript implementation, but we still have use it with care.




Thursday, March 5, 2020

How to fix the concurrent update issue in ElasticSearch with Node.js development?

if we try to update the information from two different source with ElasticSearch.


we may encounter a concurrent issue. ElasticSearch has mechanish to prevent the concurrent update.

here is the sample code to get information from bundle and book information for response.


app.put('/api/bundle/:id/book/:pgid'async(reqres)=>{
        const bundleUrl =`${url}/${req.params.id}`;
        const bookUrl=`http://${es.host}:${es.port}/${es.books_index}/book/${req.params.pgid}`;
        try{
            const [bundleResbookRes]=await Promise.all([
                rp({url:bundleUrljson:true}),
                rp({url:bookUrljson:true})
            ]);
            console.log(bundleRes);
            const {_sourcebundle_versionversion}=bundleRes;
            const {_sourcebook}=bookRes;
            console.log("if_seq_no:",if_seq_no);
            console.log("if_primary_term"if_primary_term);
            const idx=bundle.books.findIndex(book=>book.id===req.params.pgid);
            if(idx === -1){
                bundle.books.push({
                    id: req.params.pgid,
                    title: book.title
                });
            }
            const esResBody=await rp.put({
                url:bundleUrl,
                qs:{
  version: version
                    version_type: 'external',
                },
                body:bundle,
                json:true
            });
            res.status(200).json(esResBody);

        }catch(esResErr){
            res.status(esResErr.status ||502).json(esResErr.error);
        }

    })


initially i try to use the version number to resolve the concurrent issue. the error is thrown immediately after the request is made.

{
    "error": {
        "root_cause": [
            {
                "type": "action_request_validation_exception",
                "reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
            }
        ],
        "type": "action_request_validation_exception",
        "reason": "Validation Failed: 1: internal versioning can not be used for optimistic concurrency control. Please use `if_seq_no` and `if_primary_term` instead;"
    },
    "status": 400
}



based on the suggestion from the error message. i need to make couple of change, in order to fix the issue.

first we need to load the _seq_no and _primary_term from bundle response body.

 const {_sourcebundle_versionversion,  
 _seq_noif_seq_no
 _primary_term
 if_primary_term }=bundleRes;
 const {_sourcebook}=bookRes;

second, add if_seq_no and if_primary_term to the query string array 
const esResBody=await rp.put({
                url:bundleUrl,
                qs:{
                    if_seq_no: if_seq_no,
                    if_primary_term: if_primary_term
                },
                body:bundle,
                json:true
            });


Now the concurrent issue is gone. the title update is done,

 danhuideng@DESKTOP-EE785O3:/mnt/c/node/b4$ curl -s localhost:60702/api/bundle/$BUNDLE_ID |jq '._source'
{
  "name": "far",
  "books": [
    {
      "id": "pg132",
      "title": "The Art of War"
    }
  ]
}



Wednesday, March 4, 2020

How to fix ReferenceError: function is not defined Node.js?

I just encountered an issue that function is not defined. when i checked my code. the function did exist in the script file.

ReferenceError: fullUrl is not defined
    at Command.program.command.description.action (/mnt/c/node/esclu/index.js:22:17)
    at Command.listener (/mnt/c/node/esclu/node_modules/commander/index.js:301:8)
    at Command.emit (events.js:198:13)
    at Command.parseArgs (/mnt/c/node/esclu/node_modules/commander/index.js:615:12)
    at Command.parse (/mnt/c/node/esclu/node_modules/commander/index.js:458:21)
    at Object.<anonymous> (/mnt/c/node/esclu/index.js:25:9)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)


the root cause of this issue is that the order of the defined function is really matter in Node.js

i had to move this function definition to the location after the require lines.


'use strict';

const fs=require('fs');
const request=require('request');
const program =require('commander');
const pkg=require('./package.json');

const fullUrl=(path='')=>{
    let url=`http://${program.host}:${program.port}`;
    if(program.index){
        url +=program.index +'/';
        if(program.type){
            url +=program.type +'/';
        }
    }
    return urlpath.replace(/^\/*/'');
}

program
.version(pkg.version)
.description(pkg.description)
.usage('[options] <commander> [...]')
.option('-o, --host <hostname>','hostname [hostname]','localhost')
.option('-p, --port <number>','port number [9200]''9200')
.option('-j, --json','format output as json')
.option('-i, --index <name>','which index to use')
.option('-t, --type <name>''default type for bulk opertions');

program
.command('url [path]')
.description('generate the url for the options adn apth (default is /)')
.action((path='/')=>{
    console.log(fullUrl(path));
});

program.parse(process.argv);

if(!program.args.filter(arg=> typeof arg=='object').length){
    program.help();
}



Tuesday, March 3, 2020

how to use Chrome DevTools to debug Node.js Code in development?

it should a very interesting topic for debugging the Node.js Code with Chrome.


1. you must have mocha package install in your node.js project.

npm install --save --save-exact mocha@2.47.5

after the installation, you will find this package in the package.json file.

"devDependencies": {
    "chai""3.5.0",
    "mocha""2.4.5"
  },

2. set up the test run command in the scripts section

 "scripts": {
    "test:debug""node --inspect node_modules/mocha/bin/_mocha --watch --no-timeouts"
  },

3. execute npm run test:debug to generate a web socket that Chrome can connect to for debugging.

PS C:\node\databases> npm run test:debug

> databases@1.0.0 test:debug C:\node\databases
> node --inspect node_modules/mocha/bin/_mocha --watch --no-timeouts

Debugger listening on ws://127.0.0.1:9229/433a7d4f-e829-47e0-a4b4-d6f6f87df9f0
For help, see: https://nodejs.org/en/docs/inspector



  parseRDF
    √ should be a function
    √ should parse RDF content


  2 passing (52ms)



4. Launch the Chrome browse and navigate to Chrome//inspect, then click on "Open dedicated DevTools for Node" then click on the inspect link to launch the chrome DevTool.









5. click on the source tab, then navigate to the filesystem. click on the add folder button to add your source code folder. interesting, after you complete this step. you have to close the  DevTools window and click on the inspect link again to force the breakpoint get hitting.









you have to click on the allow button in order to your source code.





6 set a breakpoint on the source code that you want to debug, then open a new terminal in visual studio code to run touch yourJavscript.js.

7. the breakpoint will be hit immediately, you can start to step through your code and debug it.




How to fix ZEROMQ ipc issue in windows 10 for node.js development?

i have a line to connect to the DEALER socket.

const responder=zmq.socket('rep').connect('ipc://filer.dealer.ipc');

when i run the app. the error comes up immediately

 this._zmq.connect(addr);
            ^
Error: Protocol not supported
    at exports.Socket.Socket.connect (C:\node\microservices\node_modules\zeromq\lib\index.js:519:13)
    at Object.<anonymous> (C:\node\microservices\zmq-filer-rep-cluster.js:26:39)
    at Module._compile (internal/modules/cjs/loader.js:1139:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1159:10)
    at Module.load (internal/modules/cjs/loader.js:988:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

obviously IPC is for Linux and Unix in process communication. windows did support this kind of communication too. however windows use INPROC instead.

after i changed my code as following, the error had been fixed and running

const responder=zmq.socket('rep').connect('inproc://filer.dealer.ipc');


how to fix "TypeError: zmq.socket is not a function" with Node.js in Windows 10?

i just try to use ZEROMQ for a simple publish/subscribe Message passing app.

when i run the app with Node myApp.js. the app thrown an exception

C:\node\microservices\zmq-watch-pub.js:6
const publisher=zmq.socket('pub');     

TypeError: zmq.socket is not a function
    at Object.<anonymous> (C:\node\microservices\zmq-watch-pub.js:6:21)
    at Module._compile (internal/modules/cjs/loader.js:1139:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1159:10)
    at Module.load (internal/modules/cjs/loader.js:988:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47


 I am running in the windows 10 environment and i install zeromq@4.3.2

 "dependencies": {
    "zeromq""4.3.2"
  }

 i already encounter an error during the npm install  zeromq@4.3.2, i have to install verison 5 to avoid the error   npm install  zeromq@5

here is my current zeromq package

 "dependencies": {
    "zeromq""^5.2.0"
  }

Now i can launch the app and start monitoring the file change.

PS C:\node\microservices> node zmq-watch-pub.js target.txt
Listening for zmq subscribers....

Monday, March 2, 2020

how to write a test case that emit a close event to process the buffer after the eventemitter going offline?

Today i am continuing my learning Journey with "Node.js 8 The Right Way Practical, Server-Side Javvascript that Scales".

here is the challenge question that required to write a case against eventemitter sends JSON causing the error. follow by the close event. the eventemitter will emit a close event before going offline. the client will listen for the close event, then process the buffer data after error had been encountered.

here is the line to handle the close event that processed the data left in the buffer after throwing an error in the client.

 stream.on('close', ()=>{
            this.emit('message',JSON.parsebuffer));
        })

the following line will set up the test case. stream emit the Json Data without newline, following by emitting a close event.

 it('test case on close event',done=>{
        client.on('message'message=> {
            console.log(message);
            assert.deepEqual(message, {foo: 'bar'});
            done();
        });
        stream.emit('data','{"foo": "bar"}');
        stream.emit('close');
    });

LDJClient.js

'use strict';
const EventEmitter=require('events').EventEmitter;

class LDJClient extends EventEmitter {
    constructor(stream){
        super();
        let buffer='';
        stream.on('data',data=>{
            console.log(data);
            buffer +=data;
            let boundary=buffer.indexOf('\n');
            while(boundary !=-1){
                const input=buffer.substring(0boundary);
                buffer=buffer.substring(boundary+1);
                this.emit('message'JSON.parse(input));
                boundary=buffer.indexOf('\n');
            }
        });
        stream.on('close', ()=>{
            this.emit('message',JSON.parsebuffer));
        })
    }
    static connect(stream){
        return new LDJClient(stream);
    }
}

module.exports=LDJClient;

test-ldj-client.js

'use strict';
const assert=require('assert');
const EventEmitter=require('events').EventEmitter;
const LDJClient=require('../lib/ldj-client.js');

describe('LDJClient', ()=>{
    let stream=null;
    let client=null;

    beforeEach(()=>{
        stream=new EventEmitter();
        client=new LDJClient(stream);
    });
    it('should emit a message event for a single data event'done=> {
        client.on('message'message=> {
            assert.deepEqual(message, {foo: 'bar'});
            done();
        });
        stream.emit('data','{"foo": "bar"}\n');
        //stream.emit('data','{"foo":');
        //process.nextTick(()=> stream.emit('data', '"bar"}\n'));
    });

    it('test case on close event',done=>{
        client.on('message'message=> {
            console.log(message);
            assert.deepEqual(message, {foo: 'bar'});
            done();
        });
        stream.emit('data','{"foo": "bar"}');
        stream.emit('close');
    });
});


the output of test case is succeed. cheers





How would you pass an arbitrary number of additional parameters from process.agrv to the spwaned process?

I am following the book "Node.js 8 the right way"

here is a question to expand the functionality from book. How would you pass an arbitrary number of additional parameters from process.agrv to the spwaned process?

here is original code to monitor the file changes with command being hard code.

'use strict';
const fs=require('fs');
const spawn=require('child_process').spawn;
const filename=process.argv[2];

if(!filename){
    throw Error('A file to watch must be specified');
}
fs.watchFile(filename, ()=>{
    const ls=spawn('ls',['-l''-h'filename]);
    let output='';
    ls.stdout.on('data'chunk=>output +=chunk);
    ls.on('close', ()=>{
        const parts=output.split(/\s+/);
        console.log(parts[0], parts[4], parts[8]);
    })
});

console.log('Now watching target.txt for change.....');


 Now we can change the code handle arbitrary number of parameters. here is the spawn method child_process.spawn(command[, args][, options). we need to use an array to build the argument portion.

let options=[];
for (var i = 4i < process.argv.lengthi++) {
    options.push(process.argv[i]);
}
options.push(filename);

We can integrate the above code into our new program, then the program can accept any number of parameters. 

node watcher-spawn-cmd.js target.txt ls -l -h

 node watcher-spawn-cmd.js target.txt ls -l -h -s



'use strict';
const fs=require('fs');
const spawn=require('child_process').spawn;
const filename=process.argv[2];
const commandname=process.argv[3];

let options=[];
for (var i = 4i < process.argv.lengthi++) {
    options.push(process.argv[i]);
}
options.push(filename);

if(!filename){
    throw Error('A file to watch must be specified');
}

fs.watchFile(filename, ()=>{
    const ls=spawn(commandname, options);  
    let output='';
    ls.stdout.on('data'chunk=>output +=chunk);
    ls.on('close', ()=>{
        const parts=output.split(/\s+/);
        console.log(parts[0], parts[4], parts[8]);
    })
});

console.log('Now watching target.txt for change.....');