0.1.1 • Published 6 years ago

dealperch-auth v0.1.1

Weekly downloads
4
License
ISC
Repository
github
Last release
6 years ago

dealperch-auth

This class provides a few tools for OAuth-based development.

WithAuth HOC

This higher ordered component wraps a child component and enhances it with values received from a given getter API. It also gives the component a method to use to call a setter API while providing props that indicate the state of said setters and getters.

Please note that this HOC assumes you're using React Redux

Set Up

import Auth from "dealperch-auth";
// Tell it what key to use when connecting for the store. 
Auth.oAuthStoreKeyName = "auth";

Auth expects the store object to be in the following shape:

{
    "access_token": null
}

It must have an access token with the key literal of access_token.

Finally, you can now decorate or wrap your component with the the HOC.

const MyComponentWithAuth = Auth.withAuth({...})(MyComponent);

Getter

withAuth allows you to enrich a wrapped component with values from an API. It handles the call and provides loading

Lets say you have a basic profile component that looks like this:

import React from "react";
import PropType from "prop-types";

class Profile extends React.Component {
    constructor(props) {
        super(props);
    }
      
    render(){
        const {title, description} = this.props;
          
        return (
            <div>
                <h2>{ title }</h2>
                <p>{ description }</p>
            </div>
        )
    }
}

Profile.propTypes = {
    title: PropType.string,
    description : propType.string,
}

We don't use pure components because the HOC creates an internal reference of the component using ref

Additionally, we have a an API call that returns a promise. The parameters should always go like this:

export const getProfile =  function ({profileId}, accessToken) {
    //...
}

The HOC expects there to be two parameters. The first is an object and the second is is a string.

The object should contain whatever data needs to be used to perform the call. The second parameter should expect the access token.

Lets enhance the component with the getProfile call.

export const ProfileWithAuth = Auth.withAuth({getter: getProfile})(Profile);

Then, when we're ready to use the enhanced component, we simply pass the values expected in the object through the enhanced component's props like so:

...
    return (
        <ProfileWithAuth profileId={"12333333"} />
    )
...

The HOC will automatically call getProfile and pass the values it receives from the props into the first parameter as an object. Since the HOC has access to the store that contains the auth, it will then pass as a second argument the access token.

If we were to inspect the enhanced element, we would see that the HOC has provided a few new props.

PropTypeDescription
loadingboolA flag that indicates a promise is bing called.
loadedboolA flag that indicates the getter call has finished. This is good for preventing components from being rendered if they expect a value.
responseobjectThe full response the getter call returns.
errorobjectIf an error occurs, this object will hold the error.
cancelGetfunctionCall this function to cancel the getter method. If the component is to unmount before the promise resolves there is no need to call this. The HOC automatically stops the call.
cancelSetfunctionCall this function to cancel the setter method. Like cancelGet, this will too automatically get called when the component unmounts.

Working with the response

One way to access the response is directly through the response prop. This may not be the best way to access a response as the entire response object is here. This is more for utility purposes. There a few ways to access the response.

The HOC is meant to fit right in with reusable components. The best way to access the response is right through the props. Suppose the getProfile response returns an object like this:

{
  "links": [...],
  "count": 1,
  "_embedded": {
     "title": "Aliens",
     "description": "After floating in space for 57 years, Lt. Ripley's (Sigourney Weaver) shuttle is found by a deep space salvage team. Upon arriving at LV-426, the marines find only one survivor, a nine year old girl named Newt (Carrie Henn). But even these battle-hardened marines with all the latest weaponry are no match for the hundreds of aliens that have invaded the colony."
  }
}

As you can see, the relevant data to our profile component is nested within the _embedded object. The HOC automatically maps any [data] object nested within the response to the props. In our case, however, there is no data object.

mapResponse()

We can tell the HOC to map all the values in _embedded to the props.

export const ProfileWithAuth = Auth.withAuth(
    {
        getter: getProfile,
        mapResponse: (response) => {
            return response._embedded
        }
    }
    )(Profile);
mapResponse
argumenttypedescription
responseobjectThe entire response object.

mapResponse needs to return an obj which is to be mapped into the props. By default, it returns response.data.

Now when we inspect the props of our ProfileComponent we will see the hoc is automatically populating the title and description props.