Skip to content

Commit

Permalink
De-allocating Previously Allocated Interceptors to different respective
Browse files Browse the repository at this point in the history
Components
  • Loading branch information
Ch-sriram committed Aug 10, 2020
1 parent 42affe2 commit 56ec181
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 31 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ Firebase Common API Endpoint: <https://burger-builder-ram.firebaseio.com/>
4. Displaying a **[Spinner](https://projects.lukehaas.me/css-loaders/)** while sending a POST Request: [Commit Details](https://github.com/Ch-sriram/burger-builder/commit/2067df848d89f1b97b5d3564215b648d398468e0)
5. Handling Errors Globally using the `<Modal />` Component inside the `<withErrorHandler />` Closure HOC: [Commit Details](https://github.com/Ch-sriram/burger-builder/commit/74552c827692cadf1ef419214f360494ad350d81)
6. Retrieving Data from the **[Firebase Backend](https://burger-builder-ram.firebaseio.com/ingredients)** & Resetting Error Handler inside `withErrorHandler` Closure HOC inside the `constructor()` lifecycle method: [Commit Details](https://github.com/Ch-sriram/burger-builder/commit/25931159b2254abff5398b69b3ef1d9d877a5498)
7. De-allocating Previously Allocated Interceptors to different respective Components: [Commit Details]()
21 changes: 20 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,31 @@ import React, { Component } from 'react';
import Layout from './components/Layout/Layout.component';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder.component';

/**
* For the time being, we will just test the legibility of the
* statement:
* `axios.interceptors.request/response.eject(axiosInstance);`
* and see to it whether it will be called after the
* BurgerBuilder Component is unmounted. For that, we will just
* maintain a fake state inside the App component, to un-show
* the component depending on some condition.
*/

class App extends Component {
state = { show: true, };

componentDidMount() {
console.log("[App.js] componentDidMount...");
setTimeout(() => {
this.setState({ show: false });
}, 5000);
}

render() {
return (
<div>
<Layout>
<BurgerBuilder />
{this.state.show ? <BurgerBuilder /> : null}
</Layout>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/containers/BurgerBuilder/BurgerBuilder.component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class BurgerBuilder extends Component {
*/

// NOTE that `.json` is omitted to introduce an error deliberately
axios.get("https://burger-builder-ram.firebaseio.com/ingredients")
axios.get("https://burger-builder-ram.firebaseio.com/ingredients.json")
.then(response => {
this.setState({ ingredients: response.data },
() => {
Expand Down
60 changes: 31 additions & 29 deletions src/hoc/withErrorHandler/withErrorHandler.closureHOC.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,41 @@ import React, { Component } from 'react';
import Modal from '../../components/UI/Modal/Modal.component';
import Aux from '../Auxiliary/Auxiliary.hoc';

/**
* This withErrorHandler Closure HOC can be wrapped around any
* kind of a component and we can use this HOC as a general
* error handler.
*
* And so, whenever we wrap other components with this HOC,
* i.e., withErrorHandler Closure HOC, what we are doing is,
* (assume that we are using the same axios instance) we are
* creating and attaching multiple interceptors to the same
* axios instance.
*
* These interceptors create memory leaks when they're not
* properly released, and so, the releasing of these
* request/response interceptor instances have to be done by
* the programmer who's programming the react app manually
* inside the componentWillUnmount() lifecycle method using
* the axios.interceptors.request/response.eject(instance);
*/

const withErrorHandler = (WrappedComponent, axios) => {
return class extends Component {
constructor(props) {
super(props);
this.state = { error: null, };

axios.interceptors.request.use(req => {
// We will save the interceptor instance in the state:

this.requestInterceptor = axios.interceptors.request.use(req => {
// we want to get rid of any previous errors whenever
// we send our request
this.setState({ error: null });
return req;
});

axios.interceptors.response.use(res => res, error => {
this.responseInterceptor = axios.interceptors.response.use(res => res, error => {
// after getting the response, if there's an error,
// we'll simply handle it as follows:
this.setState({ error: error });
Expand All @@ -27,34 +48,15 @@ const withErrorHandler = (WrappedComponent, axios) => {
);
}

componentDidMount() {
console.log("[withErrorHandler.closureHOC.jsx] componentDidMount...", this.requestInterceptor, this.responseInterceptor);
}

/**
* Now, componentDidMount() is only called once the child
* components are rendered, but whenever an error occurs,
* we need it to be handled even if the child components
* are going to render. And for that, the better way of
* handling errors during axios requests/responses will
* be inside the componentWillUpdate() lifecycle method,
* and as it is deprecated now, we can handle the axios
* related errors inside the constructor() lifecycle hook.
*
* And so, we will comment the code below, and update the
* constructor() method as shown above.
*/
// componentDidMount() {
// axios.interceptors.request.use(req => {
// // we want to get rid of any previous errors whenever
// // we send our request
// this.setState({ error: null });
// return req;
// })
// axios.interceptors.response.use(res => res, error => {
// // after getting the response, if there's an error,
// // we'll simply handle it as follows:
// this.setState({ error: error });
// return Promise.reject(error);
// })
// }
componentWillUnmount() {
console.log("[withErrorHandler.closureHOC.jsx] componentWillUnmount...", this.requestInterceptor, this.responseInterceptor);
axios.interceptors.request.eject(this.requestInterceptor);
axios.interceptors.response.eject(this.responseInterceptor);
}

errorConfirmedHandler = () => {
this.setState({ error: null });
Expand Down

0 comments on commit 56ec181

Please sign in to comment.