Last active
October 11, 2017 04:51
-
-
Save Dajust/a0a17990c42d9b5ee27a208b301ad964 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import { PropTypes } from "prop-types"; | |
import { postData, getLikeBusinessEndpoint } from "../../utils/"; | |
import CheckAuth from "../checkAuth/CheckAuth"; | |
class LikeBusinessButton extends Component { | |
state = { | |
isLiked: this.props.isLiked | |
}; | |
static propTypes = { | |
isLiked: PropTypes.number.isRequired, | |
businessId: PropTypes.number.isRequired, | |
user: PropTypes.object, | |
location: PropTypes.object.isRequired, | |
AccessToken: PropTypes.string | |
}; | |
handleLikeBusiness = () => { | |
console.log("handleLikeBusiness method in Like.js fired!"); | |
const { isLiked } = this.state; | |
this.setState(() => ({ isLiked: isLiked == 1 ? 0 : 1 })); | |
postData( | |
{}, | |
getLikeBusinessEndpoint( | |
this.props.businessId, | |
isLiked == 1 ? 0 : 1, | |
this.props.AccessToken, | |
this.props.user.UserId, | |
// undo the like/unlike if the action was not succesful. | |
data => | |
data.StatusCode != 1 && | |
this.setState(() => ({ isLiked: isLiked == 1 ? 0 : 1 })) | |
) | |
); | |
}; | |
render() { | |
const { isLiked } = this.state; | |
return ( | |
<CheckAuth user={this.props.user} intentPage={this.props.location.pathname}> | |
{onCheckAuth => ( | |
<a | |
onClick={e => { | |
e.preventDefault(); | |
onCheckAuth(this.handleLikeBusiness); | |
}} | |
style={{ color: isLiked == 1 ? "red" : "" }} | |
className="split nripple-wrapper" | |
> | |
<div className="nripple js-ripple"> | |
<span className="nripple__circle" /> | |
</div> | |
<div className="nlisting-sort-nav sticky-sort-nav"> | |
<i className="icon-heart" /> | |
</div> | |
</a> | |
)} | |
</CheckAuth> | |
); | |
} | |
} | |
export default LikeBusinessButton; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So line 49 is responsible for swapping red/gray color based on the
isLiked
variable, from line 42, which is reading from the component state, which in turn is reading from the passed [isLiked
props in line 9.So we start by hardcoding the
isLiked
variable to be 1 or 0, to see if the Button actually changes colors.If that passed, that means the logic in line 50 is fine. Now we proceed to logging, using
console.log()
what the theisLiked
props is actually returning in line 9.If the props is returning the expected values, it's time to look at somewhere else.
After logging, we found that the props is always returning one value, 0, so the button is never changing its color.
So could it be a problem from the endpoint? Testing the endpoint from PostMan or curl ( I use curl ) we find the endpoint is fine.
So we progress.
On line 48, we're passing to
CheckAuth
Component thehandleLikeBusiness
method in line 20, whichCheckAuth
Component will in turn pass toAuthenticate
Component, soAuthenticate
will call the method, when it's done login.Did all those actually happen? A quick way to find out is to drop a console.log() on the first line of the
handleLikeBusiness
, that will help us know if the method was ever called.After that log, we found that the method was actually called. So, probably something is wrong with the method itself.
Looking closely, we see that the
handleLikeBusiness
is calling some utility function -postData
.postData
happens to be a function that posts data to the server given the required parameters. So the next question is, is thehandleLikeBusiness
actually passing the right parameters topostData
?Digging further, we found that none of the parameters are actually changing from what they were before the Authentication was initiated and after the Authentication was completed. Meanwhile, we needed one of those parameters, the
this.props.AccessToken
on line 31, to change to the new AccessToken returned from the Authentication phase.A little background on AccessToken parameter. We are using, JWT authentication. So the server always gives a new user a Guest AccessToken that will help him Access/Read/Get the information in the system. But to Write/Post to the system, you'll need a User AccessToken, tied to the logged-in user. So passing that AccessToken, the system will recognize the user performing the like action.
So it appears that the author of the
handleLikeBusiness
has assumed that after theAuthenticate
Component is done with login, it will update theApp
Component with the new AccessToken, then theApp
Component, in turn, will pass the new AccessToken to the rest of the Components as props. Thinking that the time thehandleLikeBusiness
is eventually called, the Like Component must have gotten a new AccessToken, the User AccessToken, so it will use to send the Like action.Unfortunately, there is something called Closure in JavaScript, which is the Author evidently did think of. Closure is the ability of a function to remember it's Lexical Scope even if it's called outside of the lexical scope. Ahh..., if you're not a good JavaScript developer that's jargon. But trust me, there is Closure 😄. The point is, the
handleLikeBusiness
will still retain or REMEMBER all the value of all variables it references during the time it was called. In our case, it still remembers the old AccessToken props, which is a wrong AccessToken for posting to the system.To fix it, we'll modify the
handleLikeBusiness
method to accept AccessToken as a parameter instead of reading it from the props. So let's go fix it!