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; |
Author
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
isLikedvariable, from line 42, which is reading from the component state, which in turn is reading from the passed [isLikedprops in line 9.So we start by hardcoding the
isLikedvariable 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 theisLikedprops 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
CheckAuthComponent thehandleLikeBusinessmethod in line 20, whichCheckAuthComponent will in turn pass toAuthenticateComponent, soAuthenticatewill 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
handleLikeBusinessis calling some utility function -postData.postDatahappens to be a function that posts data to the server given the required parameters. So the next question is, is thehandleLikeBusinessactually 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.AccessTokenon 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
handleLikeBusinesshas assumed that after theAuthenticateComponent is done with login, it will update theAppComponent with the new AccessToken, then theAppComponent, in turn, will pass the new AccessToken to the rest of the Components as props. Thinking that the time thehandleLikeBusinessis 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
handleLikeBusinesswill 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
handleLikeBusinessmethod to accept AccessToken as a parameter instead of reading it from the props. So let's go fix it!