Wednesday 21 July 2021


How to resolve JavaScript Cross Browser Compatibility Issues

 

Why is JavaScript browser compatibility an issue in the first place?

Early on, in the 1990s, the two main browsers globally used were Internet Explorer and Netscape implemented scripting in fundamentally different ways – Netscape used JavaScript, IE used JScript and also offered VBScript. JavaScript and JScript have some level of alignment since they both functioned on the ECMAScript specification. But on multiple levels, the code was implemented in contrasting and even conflicting ways, which made developing for both browsers exceptionally tedious.

Even into the 2000s, browser compatibility remained a concern for JavaScript. Since every browser runs a unique rendering engine, web elements are processed and displayed in different ways. Libraries like jQuery have made things easier by resolving and eliminating differences in how JS is implemented in various browsers. Consequently, devs only have to generate one block of code and let the library reconcile browser-based differences in the background.

However, errors in JS due to browser differences continue to plague developers. Though their occurrence is less frequent than before, they still need to be dealt with quickly and cohesively. This article will explore these issues and offer a few solutions for the same.



Common Javascript Browser Compatibility Issues

  • Primarily errors in JavaScript browser compatibility pop up when website developers try to use modern JavaScript features that are not supported on older browsers or browser versions. For example, ECMAScript 6 / ECMAScript Next is not supported in IE11. In case, you want to test your website compatibility on older browser versions, check this out. Any feature implemented with ES6 will essentially not work on this browser. A few examples of newer JS features unsupported on older browsers are:
    1. Promises are excellent for executing asynchronous operations, but they are not supported in IE.
    2. Arrow functions offer a more concise and usable syntax to craft anonymous functions. It is not supported on IE and Safari.
    3. On declaring Strict mode on top of JS code, it is parsed more rigorously with numerous rules, causing more warnings and errors to be flagged. Using Strict mode creates cleaner and more efficient code. But it isn’t supported uniformly across all browsers.
    4. With typed arrays, JS code can access and modify raw binary data. Along with modern browsers, this feature is only supported by IE10 and above. Did you know, how to test your website on the latest IE versions?

    Several necessary APIs are also unsupported on older browsers – IndexedDB API, Web Storage API, Web Workers API, WebGL API, Web Audio API, WebRTC API, WebVR API.


How to solve Javascript Browser Compatibility Issues?

  • To start with, devs must figure out if a JavaScript function is compatible with older browsers and browser versions. Use online tools like caniuse to identify which feature is supported on which browser/version and code accordingly.
  • Use JavaScript Transpiling: Transpiling converts JS code using the latest features (ES6, for example) to code suitable for older browsers. There are tools for JS transpiling such as Babel, which makes this a piece of cake.
  • Use Polyfills: These are third-party JS files that work similarly to JS libraries. However, polyfills are also capable of providing new functionalities. For example, a polyfill can be used to support ES6-based features in browsers that fundamentally don’t.
  • Use Linters: A linter scrutinizes code to check for bugs, programming errors, stylistic anomalies, undeclared variables, and the like. JS linters go a long way in maintaining code quality without requiring human validation. It is possible to adjust linters to certain levels of scrutiny, AKA error flagging/reporting. Popular JS linters include JSLint and ESLint. It is advisable to download a code editor with a built-in linter plugin applicable to JavaScript code. Atom, an open-source IDE, is quite helpful in this regard. It allows devs to install JSLint, among others, to comb through their source code.
  • Use browser developer tools/dev tools that help to debug JavaScript. In most browsers, the JavaScript console will flag and report errors in code. Use the Console API to allow JS source code to communicate with the browser’s JS console. Console API’s most widely used feature is console.log(), but study and apply its other functions to increase debugging efficiency.
  • Use the JavaScript debugger (Firefox), Chrome DevTools (Chrome), Safari Web Development Tools (Safari), and similar counterparts to delve deeper into the code and add breakpoints – junctures where code execution stops, and the developer can examine its operation in the environment so far.
  • Check browser compatibility of JavaScript by testing websites on real browsers. All the debugging in the world will not match up to the ease and accuracy of monitoring website behavior in real user conditions. Among many other reasons, detecting browser compatibility flaws in JS code makes cross browser testing indispensable in website development.
RRef: 
https://www.browserstack.com/guide/resolve-javascript-cross-browser-compatibility-issues

Friday 25 June 2021

React - Ag-grid - Column date converions with moment.js

React - Ag-grid - Column date converions with moment.js

--------------------------------------------------------


projectCMD:>npm install --save moment react-moment


react-Ag-grid-component.js

-------------------------------

import * as moment from 'moment';


const agGridColumn = [

{

headerName: 'Employee Name',

field: 'empName',

},

{

headerName: 'Date of Birth',

field: 'dob',

cellRenderer: (data) => {

return moment(data.createdAt).format('MM/DD/YYYY HH:mm')

}

},

Thursday 24 June 2021

React | Types of Routers - 3 types

 ReactJS | Types of Routers - 3 types

===========================


Memory Router

Browser Router

Hash Router


1Memory Router

---------------------

Pre-requisite: Before start this article you need to have basic knowledge of React Router.


Memory Router: Memory router keeps the URL changes in memory not in the user browsers. It keeps the history of the URL in memory (does not read or write to the address bar so the user can not use the bowser’s back button as well as the forward button. It doesn’t change the URL in your browser. It is very useful for testing and non-browser environments like React Native.


Syntax:

import { MemoryRouter as Router } from 'react-router-dom';



2.Browser Router

------------------


Browser Router: It uses HTML 5 history API (i.e. pushState, replaceState and popState API) to keep your UI in sync with the URL. It routes as a normal URL in the browser and assumes that the server is handling all the request URL (eg., /, /about) and points to root index.html. It accepts forceRefresh props to support legacy browsers which doesn’t support HTML 5 pushState API


Syntax:

import { BrowserRouter as Router } from 'react-router-dom';


3.Hash Router:

------------------


 Hash router uses client-side hash routing. It uses the hash portion of the URL (i.e. window.location.hash) to keep your UI in sync with the URL. Hash portion of the URL won’t be handled by the server, the server will always send the index.html for every request and ignore the hash value. It doesn’t need any configuration in the server to handle routes. It is used to support legacy browsers which usually don’t support HTML pushState API. It is very useful for the legacy browsers or you don’t have a server logic to handle the client-side. This route isn’t recommended to be used by the react-router-dom team.


Syntax:

import { HashRouter as Router } from 'react-router-dom';





import React, { Component } from 'react'; 

import { BrowserRouter as Router, Route, Link, Switch }   from 'react-router-dom';   /// instead of BrowserRouter, some many routes need to be added.

  

import Home from './component/home'; 

import About from './component/about'; 

import Contact from './component/contact'; 

import './App.css'; 

   

class App extends Component { 

  render() { 

      return ( 

        <Router> 

            <div className="App"> 

                <ul className="App-header"> 

                  <li> 

                      <Link to="/">Home</Link> 

                  </li> 

                  <li> 

                      <Link to="/about">About Us</Link> 

                  </li> 

                  <li> 

                      <Link to="/contact">

                        Contact Us

                      </Link> 

                  </li> 

                </ul> 

                <Switch> 

                  <Route exact path='/' 

                      component={Home}>

                  </Route> 

                  <Route exact path='/about' 

                      component={About}>

                  </Route> 

                  <Route exact path='/contact' 

                      component={Contact}>

                  </Route> 

                </Switch> 

            </div> 

        </Router> 

    ); 

  } 

   

export default App; 


Monday 21 June 2021

Renderforest: Online Video, Logo and Website Maker

Renderforest offers you the best online branding tools to create high-quality videos, logos, graphics, mockups, and websites with minimal time and effort. 


Renderforest offers you the best online branding tools to create high-quality videos, logos, graphics, mockups, and websites with minimal time and effort.


https://www.renderforest.com/templates



Tuesday 15 June 2021

React fun comp -CKEditor - 2 way Data Binding - Compare with Textarea and Editorpreview with unsafeHTML

 React fun comp -CKEditor - 2 way Data Binding - Compare with Textarea and Editorpreview with unsafeHTML

=========================================================================


import React, { useState } from 'react'; import PropTypes from 'prop-types';

import CKEditor from 'ckeditor4-react'; 

const TwoWayBinding = ()=> { 

const[data, setData] = useState('<p>React is really <em>nice</em>!</p>');


 function onEditorChange( evt ) 

 { 

 setData(evt.editor.getData()); 

 } 

 function handleChange( changeEvent ) 

 {

 setData(changeEvent.target.value); 

 }

 return (

<div>

  <CKEditor data="{data}" onChange="{onEditorChange}" />

  <label>

Change value:

<textarea defaultValue="{data}" onChange="{handleChange}" />

  </label>

  <EditorPreview data="{data}" />

</div>

); 




function EditorPreview(props) 

return (

<div className="editor-preview">

  <h2>Rendered content</h2>

  <div dangerouslySetInnerHTML="{" { __html: props.data } }></div>

</div>

); 

EditorPreview.defaultProps = { data: '' };


EditorPreview.propTypes = { data: PropTypes.string };


export default TwoWayBinding;


Saturday 12 June 2021

React, Angular Rich Text editor - CKEditor npm module

 React, Angular Rich Text editor - CKEditor npm module

==========================================


In order to create an editor instance in React, install the ckeditor4-react npm package as a dependency of your project:

React:

=======


Project_cmd:>npm install ckeditor4-react


After installing, the CKEditor 4 React component can be imported in your JavaScript code:


import CKEditor from 'ckeditor4-react';


e.g:


import React, { Component } from 'react';

import CKEditor from 'ckeditor4-react';


class App extends Component {

    render() {

        return (

            <div className="App">

                <h2>Using CKEditor 4 in React</h2>

                <CKEditor

                    data="<p>Hello from CKEditor 4!</p>"

                />

            </div>

        );

    }

}


export default App;


Angular:

========


In order to create an editor instance in Angular, install the ckeditor4-angular npm package as a dependency of your project:


Project_cmd:>npm install ckeditor4-angular


After installing, import CKEditorModule to your application:


import { CKEditorModule } from 'ckeditor4-angular';


@NgModule( {

    imports: [

        ...

        CKEditorModule,

        ...

    ],

    …

} )


e.g:


The initial data of the WYSIWYG editor. It can be a static value:


<ckeditor data="<p>Hello, world!</p>"></ckeditor>

or a shared parent component’s property:

import { CKEditor4 } from 'ckeditor4-angular/ckeditor';

@Component( {

    ...

} )

export class MyComponent {

    public editorData = '<p>Hello, world!</p>';

}

<ckeditor [data]="editorData"></ckeditor>


Integrated with ngModel:

------------------------


To use it, first create a model in your component:


@Component( {

    ...

} )

export class MyComponent {

    public model = {

        editorData: '<p>Hello, world!</p>'

    };

    ...

}

Then you can use the model in the template to enable the two-way data binding.


<ckeditor [(ngModel)]="model.editorData"></ckeditor>

Thursday 10 June 2021

React File Upload - import CSV Axios POST

 


React File Upload - import CSV Axios POST - (blob from Spring Boot)

------------------------------------------------------------------------


<div className="form-group files color">

  <label>Upload Your File </label>

  <input type="file" className="form-control" name="file" onChange={onFileChangeHandler}/>

</div>



onFileChangeHandler = (e) => {

e.preventDefault();


setSelectedFile: e.target.files[0]


const formData = new FormData();

formData.append('file', selectedFile);

fetch('http://localhost:8080/upload', {

method: 'post',

body: formData

}).then(res => {

if(res.ok) {

console.log(res.data);

alert("File uploaded successfully.")

}

});

};



Upload specfic button to make API call

-----------------------------------------------

<input type="file" className="form-control" name="file" onChange={onFileChangeHandler}/>


<Button type="button"  onClick={() => uploadChanges()}>Upload</Button>





onFileChangeHandler = (e) => {

e.preventDefault();


setSelectedFile: e.target.files[0]

}



const uploadChanges = () => {



const formData = new FormData();

formData.append('file', selectedFile);


axios.post("/api/endPointURL, data, {

headers: {

"Content-Type": "text/plain;charset=utf8",

}

// receive two parameter endpoint url ,form data

} ).then(res => { // then print response status

console.log("response->"+res.data.statusMessage);


if(res.data.statusTxt === 'Success'){

setMessage('Uploaded Successfully');

setToastrType("success");

}else {

setMessage(res.data.errorTxt);

setToastrType("error");

}

setShowToastr(true);

})

}else{

//alert("Choose the excel and click upload");

setMessage("Choose the excel and click upload");

setToastrType("error");

setShowToastr(true);

}

}

React File Download - exportCSV Axios POST

 React File Download - exportCSV Axios POST - (blob from Spring Boot)

--------------------------------------------------------------------


component.js

---------------

import ServiceApi from './ServiceAPI';


<Button onClick={downLoadFile}> DownLoad</Button>



function downLoadFile(){


ServiceApi.exportCSV(postData).then( response =>{

const url = window.URL.createObjectURL(new Blob([response.data]));

const link = document.createElement('a');

link.href = url;

link.setAttribute('download', 'FileName.xls'); //or any other extension

document.body.appendChild(link);

link.click();

});


}



ServiceAPI.js

------------------


import axios from 'axios';


class ServiceApi {


exportCSV(postData){

return axios.post('/api/endPointURL',postData, {ContentDisposition: "attachment;filename=report.xls", responseType:

'blob'} ).catch(function(error) {

console.log(error);

});

}


export default new ServiceApi()


Tuesday 8 June 2021

React- Hooks- Gloabal spinner for react applicaiton

 React- Hooks- Gloabal spinner for react application

======================================


src/hooks/useFullPageSpinner.js

-------------------------------


import React, { useState } from 'react';


import { Spinner } from '@mat-ui/spinner';

import { AriaAnnouncerProvider } from '@mat-ui/aria-announcer';


const useFullPageSpinner = () => {


  const [loading, setLoading] = useState(false);



  return [

    loading ?     <>  <AriaAnnouncerProvider>

                          <Spinner style={{ position: "absolute", top: "50%", left: "50%" , zIndex:1000}} className="circular-spinner large" />

                      </AriaAnnouncerProvider>

                  </>: null,

    () => setLoading(true),   // show the spinner

    () => setLoading(false)  // hide the spinner

   ]

}

export default useFullPageSpinner;



src/App/componets.js

--------------------


import React from 'react';


import useFullPageSpinner from "../hooks/useFullPageSpinner";



App () {


  const [loader, showLoader, hideLoader] = useFullPageSpinner();

  const [ userData, setUserData] = useState([]);


   useEffect( () =>{

    loadUserData();

  },[]);


  function loadUserData(){

    showLoader();

    api.get('/api/endpoint').then( res =>{

      hideLoader();

      if(res.status){

        console.log(res);

        setUserData(res.data);

      }

      else{

        setUserData([]);

      }

    });

  }

  return (


    <loader>


     { userData.map( item=> <div >{ itemv} </div>) }

   


    </>


  )

}

React - CORS issue, Axios API call in one place to entire app, Service componet DI , component - 3 ways

 React - Axios call - hooks based - 3 types API connection - CORS issue fix

===========================================================================

cmd:>npx create-react-app reactProject


cd reactProject


....


develop some pages/component/screens in react projects

.....


reactProject:> npm i Axios


verify the axios version at package.json


Avoid the cors issue in local development, while prod - both UI and service need to be in same place.

package.json

-----------------


"proxy": "http://localhost:8080",

"engines": {

"node": "^12",

"npm": "^6"

},


Best - Method:1


src/utils/api.js

----------------------


import axios from 'axios';



const call = method => (url, { body, query, headers } = {}) => {

return axios({

method,

baseURL: url, //baseURL: `http://localhost:8080${url}`,

data: body,

headers, //headers:{"Access-Control-Allow-Origin": "*"},

params: query

})

.then(response => response.data)

.catch(function(error) {

console.log(error);

});

};


export default {

get: call('GET'),

post: call('POST'),

put: call('PUT'),

delete: call('DELETE')

};




App.js

-------

useEffect( () =>{

// global get,post,put methos, just pass end point url of API, Error handling done in one place.


const userData = api.get('/api/endpoint');

console.log(userData)

});




Method:2

----------


src/services/serviceApi.js

---------------------------

import axios from 'axios';


class ServiceApi {


getUserData() {

return axios.get('/api/endPoint').catch(function(error) {

console.log(error);

});

}


getUserInfoData() {

return axios.get('/api/user').catch(function(error) {

console.log(error);

});

}

}



export default new ServiceApi()



App.js

------

import ServiceApi from '../services/serviceApi';


useEffect( () =>{

ServiceApi.getUserData().then(res => {

console.log(res.data.data);

//setData(res.data.data[0]);

})


});


Method:3

--------

component.ts

-------------


import axios from 'axios'; // method:3


useEffect( () =>{

axios.get('/api/endpoint').then ( response =>{

console.log(response)

}).catch( function(error){

console.log(error)

});

},[])

Sunday 30 May 2021

React - Functional - Dynamic Form

 import React, { useState } from 'react';


const Form = () => {

    const [ownerState, setOwnerState] = useState({

        owner: '',

        description: '',

    });


    const [cateState, setCateState] = useState({

        name: '',

        age: '',

    });


    const [cats, setCats] = useState([]);


    const handleOwnerChange = (e) => {

        setOwnerState({

        ...ownerState,

        [e.target.name]: [e.target.value],

    });

        setCateState([

            ...cats,

            cateState,

        ])

        

    };


    const blankCat = { name: '', age: '' };

    const [catState, setCatState] = useState([

        { ...blankCat },

    ]);


    const addCat = () => {

        setCatState([...catState, { ...blankCat }]);

    };


    const formSubmit = (e) =>{

        e.preventDefault();

        console.log(catState,ownerState);

    }


    return (

        <form  onSubmit={formSubmit}>

            {/* <label htmlFor="owner">Owner</label>

            <input

                type="text"

                name="owner"

                id="owner"

                value={ownerState.owner}

                onChange={handleOwnerChange}

            />

            <label htmlFor="description">Description</label>

            <input

                type="text"

                name="description"

                id="description"

                value={ownerState.description}

                onChange={handleOwnerChange}

            /> */}

            <input

                type="button"

                value="Add New Cat"

                onClick={addCat}

            />

            {

                catState.map((val, idx) => {

                    const catId = `name-${idx}`;

                    const ageId = `age-${idx}`;

                    return (

                        <div key={`cat-${idx}`}>

                            <label htmlFor={catId}>{`Cat #${idx + 1}`}</label>

                            <input

                                type="text"

                                name={catId}

                                data-idx={idx}

                                id={catId}

                                className="name"

                                onChange={handleOwnerChange}

                            />

                            <label htmlFor={ageId}>Age</label>

                            <input

                                type="text"

                                name={ageId}

                                data-idx={idx}

                                id={ageId}

                                className="age"

                                onChange={handleOwnerChange}

                            />

                        </div>

                    );

                })

            }

            <input type="submit" value="Submit" />

        </form>

    );

};


export default Form;

React Class based - Dynamic Form -

 import React from "react";



class Form extends React.Component {

  state = {

    devices: [{name:"", password:""}],  

  }

handleChange = (e) => {

    if (["name", "password"].includes(e.target.className) ) {

      let devices = [...this.state.devices]

      devices[e.target.dataset.id][e.target.className] = e.target.value.toUpperCase()

      this.setState({ devices }, () => console.log(this.state.devices))

    } else {

      this.setState({ [e.target.name]: e.target.value.toUpperCase() })

    }

  }

addCat = (e) => {

    this.setState((prevState) => ({

    devices: [...prevState.devices, {name:"", password:""}],

    }));

  }

handleSubmit = (e) => { 

    e.preventDefault() 

    alert(JSON.stringify(this.state.devices));

}

render() {

    let { devices} = this.state

    return (

      <form onSubmit={this.handleSubmit} onChange={this.handleChange} >

        {/* <label htmlFor="name">Owner</label> 

        <input type="text" name="owner" id="owner" value={owner} />

        <label htmlFor="description">Description</label> 

        <input type="text" name="description" id="description" value={description} /> */}

        <button onClick={this.addCat}>Add new cat</button>

        {

          devices.map((val, idx)=> {

            let deviceId = `Device Name-${idx}`, passwordId = `Password-${idx}`

            return (

              <div key={idx}>

                <label htmlFor={deviceId}>{`Device #${idx + 1}`}</label>

                <input

                  type="text"

                  name={deviceId}

                  data-id={idx}

                  id={deviceId}

                  value={devices[idx].name} 

                  className="name"

                />

                <label htmlFor={passwordId}>password</label>

                <input

                  type="password"

                  name={passwordId}

                  data-id={idx}

                  id={passwordId}

                  value={devices[idx].password} 

                  className="password"

                />

              </div>

            )

          })

        }

        <input type="submit" value="Submit" /> 

      </form>

    )

  }

}

export default Form;

Friday 8 January 2021

AWS - Free Tier - Apply coupon Code

 

How do I add a promotional code to my AWS account?


I received a promotional code or credit for AWS services. How do I add it to my AWS account?

Resolution

You can add a promotional code to your AWS account by doing the following:

  1. Open the Credits page of the Billing and Cost Management console.
  2. For Promo Code, enter the promotional code.
  3. For Please type the characters as shown above, enter the code shown in the CAPTCHA.
  4. Choose Redeem.

If the promotional code was entered correctly, is valid, hasn't expired, and hasn't been previously redeemed, it is added automatically to your AWS account.