Categories
JavaScript Answers

How to Declare Static Constants in JavaScript ES6 Classes?

Sometimes, we may want to declare static constants in our JavaScript classes.

In this article, we’ll look at how to declare static constants in JavaScript ES6 classes.

Add Getters in Our Class

To declare static constants in our ES6 classes, we can declare constants outside the class and add getters that return the constants in our class.

For instance, we can write:

const constant1 = 3,
  constant2 = 2;
class Example {
  static get constant1() {
    return constant1;
  }

  static get constant2() {
    return constant2;
  }
}

console.log(Example.constant1)
console.log(Example.constant2)

We declare constant1 and constant2 .

Then in the Example class, we create the constant1 and constant2 getters.

We add the static keyword before get so that we can make the static.

Then in the getter function, we return the constant1 and constant2 values respectively.

Likewise, we can write:

class Example {
  static get constant1() {
    return 3
  }

  static get constant2() {
    return 2
  }
}

Object.freeze(Example);
console.log(Example.constant1)
console.log(Example.constant2)

which is equivalent to what we have written above.

So when we log the values of Example.constant1 and Example.constant2 , we see 3 and 2 respectively.

Object.freeze

We can freeze the class to make the whole class immutable.

To do this, we write:

class Example {}
Example.constant1 = 3
Example.constant2 = 2
Object.freeze(Example);
console.log(Example.constant1)
console.log(Example.constant2)

We add our static properties with:

Example.constant1 = 3
Example.constant2 = 2

This works since classes are constructor functions, which are objects.

This also means we can use the Object.freeze method on Example to make the Example class immutable.

So we can log the values of the Example.constant1 and Example.constant2 properties and get their values.

We should see 3 and 2 respectively.

Conclusion

We can declare static constants in our JavaScript class by declaring static getters that returns constants declared outside the class.

Also, we can freeze the class with the Object.freeze method since it’s a regular object.

This makes the class immutable.

Categories
JavaScript Answers

How to Run a Function When a Page has Fully Loaded with JavaScript?

Sometimes, we want to run some code when our web page is fully loaded.

In this article, we’ll look at how to run a function when a page has fully loaded with JavaScript.

Listen to the load Event

The load event is triggered when a page is fully loaded.

Therefore, we can listen to the load event by attaching an event handler function to it to run code when the page is fully loaded.

For instance, we can write:

window.addEventListener('load', () => {  
  console.log("page is loaded")  
})

We call window.addEventListener to listen to the load event triggered on the page.

In the 2nd argument, we pass in a callback function that runs when the load event is triggered.

Therefore, we should see 'page is loaded' logged when the web page is loaded.

Listen to the DOMContentLoaded Event

Likewise, we can listen to the DOMContentLoaded event which is also triggered when the page is fully loaded.

So we can attach an event handler to it the same we did with the load event.

For instance, we can write:

window.addEventListener('DOMContentLoaded', () => {  
  console.log("page is loaded")  
})

to run the callback in the 2nd argument when the page is fully loaded.

Therefore, we should see 'page is loaded' logged when the web page is loaded.

Set the window.onload Method

We can set the window.onload method to a function we want to run code when the page is fully loaded.

This is because window.onload runs when the page is fully loaded.

To do this, we write:

window.onload = () => {  
  console.log("page is loaded")  
}

We just set the onload property to a function we want to run when the page is loaded.

Therefore, we should see 'page is loaded' logged when the web page is loaded.

Conclusion

There are several ways we can use to run a function when a web page fully loaded with JavaScript.

Categories
React

How to make async mutations with React Query?

The React Query library lets us make HTTP requests easily in our React apps.

In this article, we’ll look at how to make async mutations with React Query?

mutateAsync

The mutateAsync method lets us call mutate is an async manner.

It returns a promise which lets us commit our mutation request in an async manner, which doesn’t hold up the JavaScript main thread.

For instance, we can write:

import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";

export default function App() {
  const { reset, mutateAsync } = useMutation((data) =>
    axios.post("https://jsonplaceholder.typicode.com/posts", data)
  );
  const [title, setTitle] = useState("");

  const onCreateTodo = async (e) => {
    e.preventDefault();
    try {
      const todo = await mutateAsync({
        title
      });
      console.log(todo);
    } catch (error) {
      console.log(error);
    } finally {
      console.log("done");
    }
  };

  return (
    <div>
      <form onSubmit={onCreateTodo}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <br />
        <button type="submit">Create Todo</button>
        <button type="button" onClick={() => reset()}>
          reset
        </button>
      </form>
    </div>
  );
}

We call mutateAsync which returns a promise with the response data from the axios.post call.

Retry Mutations

With React Query, we can easily retry our mutation HTTP request if it returns an error.

We just have to set the retry option to the number of times we want to retry.

For instance, we can write:

import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";

export default function App() {
  const { reset, mutateAsync } = useMutation(
    (data) => axios.post("https://jsonplaceholder.typicode.com/posts", data),
    {
      retry: 3
    }
  );
  const [title, setTitle] = useState("");

  const onCreateTodo = async (e) => {
    e.preventDefault();
    try {
      const todo = await mutateAsync({
        title
      });
      console.log(todo);
    } catch (error) {
      console.log(error);
    } finally {
      console.log("done");
    }
  };

  return (
    <div>
      <form onSubmit={onCreateTodo}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <br />
        <button type="submit">Create Todo</button>
        <button type="button" onClick={() => reset()}>
          reset
        </button>
      </form>
    </div>
  );
}

We call the useMutation hook with an object that has the retry property set to 3 to retry up to 3 times if the mutation request fails.

Invalidate Queries

We can invalidate queries so we can mark a query request as stale and make the request again automatically.

For instance, we can write:

index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "react-query";
import App from "./App";

const queryClient = new QueryClient();
queryClient.invalidateQueries("yesNo", { exact: true });

const rootElement = document.getElementById("root");
ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <StrictMode>
      <App />
    </StrictMode>
  </QueryClientProvider>,
  rootElement
);

App.js

import axios from "axios";
import React from "react";
import { useQuery } from "react-query";
export default function App() {
  const { data } = useQuery("yesNo", () => axios("https://yesno.wtf/api"));

  return <div>{JSON.stringify(data)}</div>;
}

We call:

queryClient.invalidateQueries("yesNo", { exact: true });

to invalidate the query by the key.

exact set to true means the key of the query request must match exactly before it’s invalidated.

Conclusion

We run mutation requests asynchronously and invalidate query requests to make the request again with Reacr Query.

Categories
React

How to commit side effects in React Query mutations?

The React Query library lets us make HTTP requests easily in our React apps.

In this article, we’ll look at how to commit side effects in React Query mutations?

Mutation Side Effects

We can watch for events that are emitted when mutations are being committed.

For instance, we can write:

import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";

export default function App() {
  const { reset, mutate } = useMutation(
    (data) => axios.post("https://jsonplaceholder.typicode.com/posts", data),
    {
      onMutate: (variables) => {
        console.log(variables);
        return {};
      },
      onError: (error, variables, context) => {
        console.log(error, variables, context);
      },
      onSuccess: (data, variables, context) => {
        console.log(data, variables, context);
      },
      onSettled: (data, error, variables, context) => {
        console.log(data, error, variables, context);
      }
    }
  );
  const [title, setTitle] = useState("");

  const onCreateTodo = (e) => {
    e.preventDefault();
    mutate({
      title
    });
  };

  return (
    <div>
      <form onSubmit={onCreateTodo}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <br />
        <button type="submit">Create Todo</button>
        <button type="button" onClick={() => reset()}>
          reset
        </button>
      </form>
    </div>
  );
}

The onMutate method is run when the mutation request is being made.

variables has the mutation data from the data parameter.

onError is run when there’s an error with the mutation.

error has the error object.

variables is the same as before.

context has the context data which has the mutation request data.

onSuccess is run when the mutation request is successful.

data has the mutation response data.

variables and context are the same as the other callback parameters.

onSettled is run whenever a mutation request is finished regardless of whether it’s successful or not.

All the parameters are the same as before.

We can also add the same callbacks to the mutate method call.

For instance, we can write:

import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";

export default function App() {
  const { reset, mutate } = useMutation(
    (data) => axios.post("https://jsonplaceholder.typicode.com/posts", data),
    {
      onMutate: (variables) => {
        console.log(variables);
        return {};
      },
      onError: (error, variables, context) => {
        console.log(error, variables, context);
      },
      onSuccess: (data, variables, context) => {
        console.log(data, variables, context);
      },
      onSettled: (data, error, variables, context) => {
        console.log(data, error, variables, context);
      }
    }
  );
  const [title, setTitle] = useState("");

  const onCreateTodo = (e) => {
    e.preventDefault();
    mutate(
      {
        title
      },
      {
        onMutate: (variables) => {
          console.log(variables);
          return {};
        },
        onError: (error, variables, context) => {
          console.log(error, variables, context);
        },
        onSuccess: (data, variables, context) => {
          console.log(data, variables, context);
        },
        onSettled: (data, error, variables, context) => {
          console.log(data, error, variables, context);
        }
      }
    );
  };

  return (
    <div>
      <form onSubmit={onCreateTodo}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <br />
        <button type="submit">Create Todo</button>
        <button type="button" onClick={() => reset()}>
          reset
        </button>
      </form>
    </div>
  );
}

The callbacks we add to the object we pass in as the 2nd argument of mutate will run after the callbacks we added to the useMutation hook.

Conclusion

We can add callbacks to the object we pass into the useMutation hook or mutate method to watch for any events that are triggered when making our mutation request with React Query.

Categories
React

How to make mutations with React Query?

The React Query library lets us make HTTP requests easily in our React apps.

In this article, we’ll look at how to make mutations with React Query?

Mutations

Mutations let us make HTTP requests to change data on a server by creating, updating, and deleting them.

For instance, we can write:

index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "react-query";
import App from "./App";

const queryClient = new QueryClient();

const rootElement = document.getElementById("root");
ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <StrictMode>
      <App />
    </StrictMode>
  </QueryClientProvider>,
  rootElement
);

App.js

import axios from "axios";
import React from "react";
import { useMutation } from "react-query";

export default function App() {
  const { mutate, isLoading, isError, isSuccess } = useMutation((data) =>
    axios.post("https://jsonplaceholder.typicode.com/posts", data)
  );

  return (
    <div>
      <div>{isLoading && "loading"}</div>
      <div>{isError && "error"}</div>
      <div>{isSuccess && "success"}</div>
      <button
        onClick={() => {
          mutate({
            title: "foo",
            body: "bar",
            userId: 1
          });
        }}
      >
        Add Todo
      </button>
    </div>
  );
}

We call the useMutation hook with a callback that lets us make a POST request to the API to submit some data.

The callback should return a promise.

The request payload is stored in the payload parameter.

The hook returns the mutate function that lets us make the request.

isLoading is true when the request is loading.

isError is true when a request fails.

isSuccess is true when the request is successfully completed.

Alternatively, we can replace isLoading , isSuccess , and isError with the status property:

import axios from "axios";
import React from "react";
import { useMutation } from "react-query";

export default function App() {
  const { mutate, status } = useMutation((data) =>
    axios.post("https://jsonplaceholder.typicode.com/posts", data)
  );

  return (
    <div>
      <div>{status === "loading" && "loading"}</div>
      <div>{status === "error" && "error"}</div>
      <div>{status === "success" && "success"}</div>
      <button
        onClick={() => {
          mutate({
            title: "foo",
            body: "bar",
            userId: 1
          });
        }}
      >
        Add Todo
      </button>
    </div>
  );
}

'loading' status is the status when the request is loading.

'error' status is the status when the request has an error.

'success' status is the status when the request is successful.

Resetting Mutation State

We can clear the mutation request state after the request is done.

To do this, we can call the reset method:

import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";

export default function App() {
  const { reset, mutate } = useMutation((data) =>
    axios.post("https://jsonplaceholder.typicode.com/posts", data)
  );
  const [title, setTitle] = useState("");

  const onCreateTodo = (e) => {
    e.preventDefault();
    mutate({
      title
    });
  };

  return (
    <div>
      <form onSubmit={onCreateTodo}>
        <input
          type="text"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <br />
        <button type="submit">Create Todo</button>
        <button type="button" onClick={() => reset()}>
          reset
        </button>
      </form>
    </div>
  );
}

We call the reset method when we click on the reset the state returned by the useMutation hook.

Conclusion

We can make requests that change data on the server with the React Query useMutation hook.