Category: Javascript

Using ReactQuery with React instead of Axios + hooks

In your React app you can use ReactQuery and ReactQueries for request caching, background updates and stale data out of the box with zero-configuration, instead of just Axios + hooks.

UseQuery : 1 api request

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
...
const getServices = () => {
        return axios.get('https://jsonplaceholder.typicode.com/posts');
};
...
const { data, isError, isLoading } = useQuery(['services'], getServices);

if (isLoading) {
    return <p>Loading...</p>;
}

if (isError) {
    console.error('error');
}

return <ServiceComponent data={data} />;

UseQueries : 2+ api request

Index.tsx

import { useQueries } from '@tanstack/react-query';
import axios from 'axios';
...
const getServiceOne = () => {
        return axios.get('https://jsonplaceholder.typicode.com/posts');
};
...
const results: any = useQueries({
    queries: [
      { queryKey: ['serviceOne'], queryFn: getServiceOne, staleTime: Infinity },
      { queryKey: ['serviceTwo'], queryFn: getServiceTwo, staleTime: Infinity },
    ],
});

const serviceOneResult = results[0];
const serviceTwoResult = results[1];

  const isError = serviceOneResult.error || serviceTwoResult.error;
  const isLoading = serviceOneResult.isLoading || serviceTwoResult.isLoading;

  if (isLoading) {
    return <p>Loading...</p>;
  }

  if (isError) {
    console.error('error');
  }

  return (
    <ServiceComponent
      dataOne={serviceOneResult.data}
      dataTwo={serviceTwoResult.data}
    />
  );

Git : Don’t commit node_modules except a file in a library

If you are using the node_modules in your Node.JS / Javascript / Typescript project you should exclude to commit all the libraries used by your application with this line in the .gitignore file:

.gitignore

node_modules/

But, you may need to modify a file in the /node_modules folder, excluded in the .gitignore

Force commit a file in a excluded folder in .gitignore

If you want to fix a file in a library that makes some problems in your application, you may want to modify the library directly in /node_modules (the case you are using the last version of the library, you can check on https://www.npmjs.com/ if you are using the last version in your package.json)

In my case, I modified node_modules/react-native-firebase/ios/RNFirebase/notifications/RNFirebaseNotifications.m a library that is not changed since 2 years and have a problem in my application. You can of course make a git issue on the official page but if you need it to work fast, you may want to commit it directly in your project and it is fixed.

After you made the change in the library, you can commit with git add -f …

In my case:

git add -f node_modules/react-native-firebase/ios/RNFirebase/notifications/RNFirebaseNotifications.m
You can see your file to be commit in your Git Desktop, and my node_modules folder is excluded in .gitignore

Kill Node.JS service by port / Arrêter un service Node.JS avec son port

🇬🇧Dear all, is it possible you want to kill a Node.JS service with your linux machine, that is running on a specific port

Il est possible que vous voulez arrêter un processus Node.JS sur un port précis sur votre machine linux🇫🇷

Here is the magic command to find and kill the Node.JS process

Voici la commande magique qui permet de trouver et arrêter de processus avec son port

netstat -pluton
It looks like the name of the famous planet / Moyen mémo-technique on pense à cette p’tite planete

Then you should be able to find the process (PID) with the port associated

Vous devriez avec cette commande trouver le nom du processus (PID) avec le port associé

PORT 4000:

AWS Amplify : Babel error building React.JS app

Is it possible you may have an error with babel on AWS Amplify, while deploying your React.JS app:

If you click on Frontend you should be able to see the logs :

2022-01-14T17:18:36.441Z [INFO]: $ react-scripts build
2022-01-14T17:18:37.352Z [INFO]: Creating an optimized production build...
2022-01-14T17:18:38.431Z [INFO]: Failed to compile.
2022-01-14T17:18:38.433Z [INFO]: ./src/index.js
                                 Error: [BABEL] /codebuild/output/src483533555/src/app/src/index.js: Cannot find module '@babel/helper-define-map'
                                 Require stack:
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/plugin-transform-classes/lib/transformClass.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/plugin-transform-classes/lib/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/preset-env/lib/available-plugins.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/preset-env/lib/plugins-compat-data.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/preset-env/lib/normalize-options.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/node_modules/@babel/preset-env/lib/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/create.js
                                 - /codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/react-scripts/node_modules/@babel/core/lib/config/files/plugins.js
                                 - /codebuild/output/src483533555/src/app/node_modules/react-scripts/node_modules/@babel/core/lib/config/files/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/react-scripts/node_modules/@babel/core/lib/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/react-scripts/node_modules/babel-loader/lib/index.js
                                 - /codebuild/output/src483533555/src/app/node_modules/loader-runner/lib/loadLoader.js
                                 - /codebuild/output/src483533555/src/app/node_modules/loader-runner/lib/LoaderRunner.js
                                 - /codebuild/output/src483533555/src/app/node_modules/webpack/lib/NormalModule.js
                                 - /codebuild/output/src483533555/src/app/node_modules/webpack/lib/NormalModuleFactory.js
                                 - /codebuild/output/src483533555/src/app/node_modules/webpack/lib/Compiler.js
                                 - /codebuild/output/src483533555/src/app/node_modules/webpack/lib/webpack.js
                                 - /codebuild/output/src483533555/src/app/node_modules/react-scripts/scripts/build.js (While processing: "/codebuild/output/src483533555/src/app/node_modules/babel-preset-react-app/index.js")
2022-01-14T17:18:38.451Z [WARNING]: error Command failed with exit code 1.
2022-01-14T17:18:38.451Z [INFO]: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
2022-01-14T17:18:38.461Z [ERROR]: !!! Build failed
2022-01-14T17:18:38.461Z [ERROR]: !!! Non-Zero Exit Code detected
2022-01-14T17:18:38.461Z [INFO]: # Starting environment caching...
2022-01-14T17:18:38.461Z [INFO]: # Uploading environment cache artifact...
2022-01-14T17:18:38.534Z [INFO]: # Environment caching completed
Terminating logging...

In order to solve the @babel errors, you will need to install all the @babel packages:

NPM

npm install babel-core babel-loader babel-preset-env 
babel-preset-react babel-polyfill babel-runtime @babel/helpers 
@babel/helper-builder-react-jsx-experimental @babel/helper-builder-react-jsx 
@babel/helper-define-map @babel/helper-plugin-utils @babel/helper-regex

YARN

yarn add babel-core babel-loader babel-preset-env 
babel-preset-react babel-polyfill babel-runtime @babel/helpers 
@babel/helper-builder-react-jsx-experimental @babel/helper-builder-react-jsx 
@babel/helper-define-map @babel/helper-plugin-utils @babel/helper-regex

In order to run your React.JS project on Amplify, here is all the babel packages I installed to solve all problems:

  • babel-core
  • babel-loader
  • babel-preset-env
  • babel-preset-react
  • babel-polyfill
  • babel-runtime
  • @babel/helpers
  • @babel/helper-builder-react-jsx
  • @babel/helper-builder-react-jsx-experimental
  • @babel/helper-define-map
  • @babel/helper-plugin-utils
  • @babel/helper-regex

After, that, you should be able to see your React.JS app online with Amplify:

Sort your result by distance – Node.JS

Supposed that you return in your Node.JS backend a list of items, and you want to sort the results by distance.

For exemple, you do a GET /usersLocation and you have it:

[
   {
      name: "Paul",
      gender: "man",
      distance: 4.1
   },
   {
      name: "Philip",
      gender: "man",
      distance: 4.9
   },
   {
      name: "Elina",
      gender: "woman",
      distance: 2.5
   }
]

In your app you have the result to be listed by distance for exemple, so the user can know who is nearest first, and don’t have to scroll down to see that Elina is nearest. To do so, we can add this portion of code before returning the list of items:

    // items : variable containing all the items

    // SORT
    for(let a=items.length;a>0;a--)
    {
       for(let b=0;b<a-1;b++)
       {
          if(items[b].distance>items[b+1].distance) // we order by distance
          {
             // we swap the items
             tmp = items[b];
             items[b]=items[b+1];
             items[b+1]=tmp;
          }
       }
    }

    // returning the response for AWS Lambda
    const response = {
        statusCode: 200,
        body: JSON.stringify(items),
    };
    return response;
};

New response:

[
   {
      name: "Elina",
      gender: "woman",
      distance: 2.5
   },
   {
      name: "Paul",
      gender: "man",
      distance: 4.1
   },
   {
      name: "Philip",
      gender: "man",
      distance: 4.9
   }
]

Create quickly API with AWS – Lambda/API Gateway

Amazon Web Services — Wikipédia

This article is dedicated to new users to AWS – Amazon Web Services – that wants to use this cloud instead for others (Azure, Google Cloud) which seems to be the best choice at the moment. Indeed, AWS is the most complete scalable and dynamic cloud solution.

However, this is not so simple to understand all the concepts, if you look for simplicity you may be interested by Google Cloud that I used before.

In order to use API Gateway and Lamdba, you should add them in favorite in the Services:

Create your API functions in AWS Lambda

We can use AWS Lamdba to create routes that can be used for our applications.

So, you can click Create function, in order to see the form bellow.
Let’s say we want to create a route to list the products of our app, it will be a GET method and we will call it getProducts.
We will use Node.JS because I have to habit to use Javascript and Typescript but you can choose the runtime you are in ease.

Then you can click Create function, we don’t need the others settings.

You should be now able to see the function overview with the default example in the code editor:

You can try the example it will show the string “Hello from Lambda”, the response that is returned in the example.
We can now write our own function from scratch here or alternatively we can upload our code from a ZIP file.

Create our API Gateway route (HTTP)

In the overview of the Lambda function you can see the button Add trigger, you can use it to add the API event that will call our function.

Click “Add trigger”
Select “Create API”, then “HTTP API” (best for cost) and “Open” the endpoint so your app can use it

You can then click Save and so you should see your new trigger, the API Gateway trigger:

Now you can try it by going on the API endpoint link in the details.
You can use it like it in your application or you can change it by adding your own domain, for exemple api.myapp.com/getProducts
You can do that in Custom Domain Names or directly in your domain provider, in the DNS configuration, making a redirection.

Creating an API Gateway (REST API)

You could also, if you need it, use multiple methods such GET, POST, UPDATE, DELETE, … if you created a REST API Gateway :

You can then use your Lambda function for each methods you want to use.

Color picker with React.JS

Example of a color picker made with React.JS

In order to have a color picker on our React.JS application, we can use the SketchPicker library

Full example

Color: <TextField variant="outlined" id="standard-basic" style={{padding: 5, width: '90%', background: color}} value={color?color:''} onChange={(e) => { setColor(e.target.value); }} />
<SketchPicker 
   color={ color?color:'#fff' }
   onChangeComplete={ (colorSelected) => {
         setColor(`${colorSelected.hex}${decimalToHex(colorSelected.rgb.a)}`);
      } 
   }
   presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF']}
/>

Alerting user with a small messaga bubble – Snackbar – React.JS

In your web app, you will have to notice the user when he is doing some actions in your user interface. We can do it with a small message bubble called Snackbar, here is what it looks like:

How we will do it

setSnackSeverity("error");
setSnackMessage("The last cell cannot be deleted.");
setOpenError(true);

In your code, we will use these 3 lines to:
– Set the severity “error”, there are 4 types of severity

– Set the error message that will be displayed “The last cell cannot be deleted.”
– Show the error message (during few seconds)

Full example

import Snackbar from '@material-ui/core/Snackbar';
import MuiAlert, { AlertProps } from '@material-ui/lab/Alert';
function Alert(props) {
  return <MuiAlert elevation={6} variant="filled" {...props} />;
}
...
const [snackSeverity, setSnackSeverity] = useState('error');
const [openError, setOpenError] = useState(false);
const [snackMessage,setSnackMessage] = useState('Error');
...
setSnackSeverity("error");
setSnackMessage("The last cell cannot be deleted.");
setOpenError(true);
...
<Snackbar
   anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
   open={openError}
   onClose={(e)=>setOpenError(false)}
   autoHideDuration={3000} 
   >
     <Alert onClose={(e)=>setOpenError(false)} severity={snackSeverity}>
       {snackMessage}
     </Alert>
</Snackbar>

React.JS • Full list of all icons

Examples of listing the icons in React.JS / React Native

Listing all the icons

List of all the icons

Searching icons name

Searching an icon name

How to do it ?

Importing all the icons

Import the CSS your icons in /public/index.html

<link rel="stylesheet" href="http://cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css" />

Use it in your source code

Use your icons in the code source in /src/App.js like that:

<span> 
   <i class={`mdi mdi-${icon?icon:''}`} aria-hidden="true"></i>
</span>

Loop on all icons

If you want a list of icons then you can loop on the list of icons, let’s say you have put all your icons in a file called iconlist.js

export const icons = [
"ab-testing",
"abjad-arabic",
"abjad-hebrew",
"abugida-devanagari",
"abugida-thai",
"access-point",
"access-point-check",
"access-point-minus",
"access-point-network",
"access-point-network-off",
"access-point-off",
"access-point-plus",
"access-point-remove",
"account",
"account-alert",
"account-alert-outline",
"account-arrow-left",
"account-arrow-left-outline",
"account-arrow-right",
"account-arrow-right-outline",
"account-box",
"account-box-multiple",
"account-box-multiple-outline",
"account-box-outline",
"account-cancel",
"account-cancel-outline",
"account-cash",
"account-cash-outline",
"account-check",
...
];

Then you can import the icons in you App.js and use it:

import { icons } from './icons';
...
{ icons.map((icon, index) => (
   <div style={{fontWeight: 'bold'}}> <i class={`mdi mdi-${icon}`} aria-hidden="true"></i> {icon} </div>
))}

You can then add a filter if you want to check that the icons contain part of the string name :

const [searchIcon, setSearchIcon] = useState(null);
...
{ icons.filter(icon => icon.includes(searchIcon) ).map((icon, index) => (
    <div style={{fontWeight: 'bold'}}> <i class={`mdi mdi-${icon}`} aria-hidden="true"></i> {icon} </div>
  )
)}

ReactJS • Responsive UI interface

You are making a React application and you want to have a responsive user interface that works both on laptop and mobile phone ?

A solution can be to use Material UI with several layout components such :

  • Container
  • Grid
  • Hidden

The grid looks like this:

<Grid container spacing={3}>
        <Grid item xs={12}>
          <Paper className={classes.paper}>xs=12</Paper>
        </Grid>
        <Grid item xs={6}>
          <Paper className={classes.paper}>xs=6</Paper>
        </Grid>
        <Grid item xs={6}>
          <Paper className={classes.paper}>xs=6</Paper>
        </Grid>
        <Grid item xs={3}>
          <Paper className={classes.paper}>xs=3</Paper>
        </Grid>
        <Grid item xs={3}>
          <Paper className={classes.paper}>xs=3</Paper>
        </Grid>
        <Grid item xs={3}>
          <Paper className={classes.paper}>xs=3</Paper>
        </Grid>
        <Grid item xs={3}>
          <Paper className={classes.paper}>xs=3</Paper>
        </Grid>
      </Grid>

As you can see, the full width of the page is xs=12. It means the full width size is equal to 12.


You can see so that with 2 grid items of xs=6, it will be two components.
And so 4 will be 3 components on the line and 3 will be 4 components on the line.

You can use this grid items when you want to display block of contents on the page, if you know Bootstrap, it’s the same.

You can put any content inside your <Grid>, it can be a <div> for example.

Using XS, SM, MD, LG and XL

Grid SizeDeviceWeb browser width
XSMobile phone screens 0px ► 600x
SMMobile phone and tablets600px ► 960px
MDLaptop960px ► 1280px
LGLaptop1280px ► 1920px
XLDesktop1920px ► …

Using breakpoints

Using breakpoints allow you to have different grid size for different devices, which allows you to have a grid adapted for mobile phone for exemple:

You can se the size 6 for laptop (SM=6 and higher) and size is 12 for mobile phone (XS=12)

Using Hidden

You can use the <Hidden> element from Material UI to hide specific items for XS/SM/MD/LG/XL items.

<Hidden only="lg">
    <Paper className={classes.paper}>Hidden on lg</Paper>
</Hidden>