Thursday 21 October 2021
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:
- Promises are excellent for executing asynchronous operations, but they are not supported in IE.
- Arrow functions offer a more concise and usable syntax to craft anonymous functions. It is not supported on IE and Safari.
- 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.
- 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.
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:
- Open the Credits page of the Billing and Cost Management console.
- For Promo Code, enter the promotional code.
- For Please type the characters as shown above, enter the code shown in the CAPTCHA.
- 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.
-
Method 1: Offline and online Open FireFox -> Tools -> Add-ons . => Add ons Manager browser appear. Then Search type firebug. ...
-
import React, { useEffect, useState } from 'react'; import { AgGridColumn, AgGridReact } from 'ag-grid-react'; import '...