Open Side Menu Go to the Top
Register
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** ** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

01-30-2019 , 06:58 PM
I would be internally screaming "Arghhh my eyes!!!" about the lack of consistency in file/folder naming (even within the same component!). Though I am prone to that sort of mess with variable names myself on occasion. At least those are hidden away a little! I'm also not a big fan of the nesting.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 07:25 PM
Quote:
Originally Posted by suzzer99
I think the answer would apply to any kind of development.
I agree.

I don't know why components have the word "Component" in their directory, and in their file names. But that's not too bad, some people like that. I've always hated it. I used to have a DBA that insisted that if your table was named "foo" then all your columns had to start with foo_ like foo_user_id. The idea isn't bad (there can never be a mistake where you accidentally use a column from the wrong table in a join) but it also is a pain in the ass and makes simple join syntax impossible, i.e. you can no longer do

Code:
select * from users 
join groups using (user_id)
and instead have to do
Code:
select * from users u join 
groups g on (g.groups_user_id=u.users_user_id)
But some of them do and some don't. Some have -Component and some just Component. Some have one in the dir name and something else in the file name. Some are totally arbitrary like a dir name like "Registration-verify" and file names like RegistrationVerify
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 07:31 PM
Quote:
Originally Posted by suzzer99
I think the answer would apply to any kind of development.
Oh wow, yea, didn't even look at it before due to it being "web" stuff. Just the mixing of cases tilts the hell out of me and that's just after a cursory glance.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 07:34 PM
In the Programmer Competency Matrix, organization across files is just one row out of a lot. It’s entirely possible a great dev sucks at that stuff. I tend to be pretty decent at it but I have one senior dev who’s extremely talented that is absolutely atrocious at using anything outside of his one favorite IDE. I had to train him for like a day and a half on how to use git properly.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 07:41 PM
Quote:
Originally Posted by suzzer99


Let's say you had a senior front end developer who has been developing a react app for a month or so. You get a look at what he's done and this is the naming and organizational scheme he's come up with for the react components.

What would you think?
  1. Naming consistency isn't that important, seems fine.
  2. A little messy but fine.
  3. Not good, need to keep an eye on this guy and clean this up.
  4. Wtf - this is not senior dev work and a major red flag.
This is fine I guess. I'd ask him to take out like every use of the word "component" because, yeah, its a react app and its in a folder called "components". Also pick between dashes and camelcase dillhole.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 07:44 PM
I just realized this same dev also doesn't believe in using form tags. Just bare input tags with onChange that set state. Then the "submit" button is just a link with onClick to process the form.

Please tell me this is not some common react paradigm.

And this may shock you - but indentation is all over the place.

This seems bad:

Code:
  // handling the confirmation registration after entering the verification code
  hadleConfirmRegistration = async (verificationCode) => {
        const {location} = this.props;
        const {state} = location;
        const {registerVerify} = state;
        const {password,email} = registerVerify;
        // const crmIdVal =  myAccountService.getCrmId();
        this.setState({emailVal:email,passwordVal:password,crmId:crmIdVal});
    try {
            await Auth.confirmSignUp(this.state.emailVal, verificationCode);
            const user = await Auth.signIn(this.state.emailVal, this.state.passwordVal);
            console.log(user, 'user');
            this.props.history.push({pathname: crmIdVal ? '/verifyduplicate':'/dashboard', state: { email: this.state.emailVal}})
    } 
    catch (e) {
        console.log(e);
    }  
}
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 08:15 PM
I wouldn't be surprised if that dev is outsourcing his work. The wildly different case conventions are a piece, but the myComponent thing that happens in there just reeks of someone without a clue.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 08:40 PM
I think he's just copying and pasting. But yeah the clue level is very low.

Sooooo - since I've now inherited this thing, I have a somewhat noobish react question. We're using BrowserRouter and wrapping our components with withRouter - I think just so we can use props.history.push to route. Might change that but that's not the question.

The question is I have a common behavior that happens after successful login or sign up - we need to go to the back end CRM system, see if we can find the user, and route them to one page if they have a CRM ID and a different page if they don't. There are also other edge cases that get routed to other pages. Because of the vagaries of Cognito and how it integrates with the browser, I cannot just get this info from the back end when the user signs up. It has to be in a separate call.

So obviously I want to consolidate this behavior somewhere and share it amongst all the different ways and places a user can login or sign up.
  1. I could pass the props object to my service that looks up the CRM ID, and have it do the routing. But that doesn't seem like something a service should do.
  2. I could go vanilla old school and just make some shared utility method.
  3. I could wrap the components in some more global component that has a method I can call to do the post login behavior/routing.
  4. Or I could have something at the global state that gets triggered when I do something like setState({userLoggedIn: true});

The last seems like the most react-y way to do things. But it also bugs me in code when magic happens like that. How do I trace what's supposed to happen when userLoggedIn = true triggers something? Seems painful.

Edit: I thought of a 5th way that I might like. Redirect to a SignUpSuccess page that is just a spinner. That page makes the call to the back end and figures out where to route the user. Hmmm.

Last edited by suzzer99; 01-30-2019 at 08:52 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 08:58 PM
Quote:
Originally Posted by suzzer99
I just realized this same dev also doesn't believe in using form tags. Just bare input tags with onChange that set state. Then the "submit" button is just a link with onClick to process the form.

Please tell me this is not some common react paradigm.
Like this?

https://reactjs.org/docs/handling-events.html

Code:
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:02 PM
Yeah but I need the same logic in like 4 or 5 different components. So I'm trying to figure out how to share it. And there's no UI component - just logic that gets triggered after a successful login.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:05 PM
You can mix vanilla javascript in with React pretty easily I think. Like if you have a module you can import it and call a function from within your React class. I think.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:06 PM
That's not submitting a form, though. A page that submits POST data should have a form and a submit button.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:09 PM
I wish you guys all worked on stuff I actually knew anything about
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:09 PM
Quote:
Originally Posted by ChrisV
That's not submitting a form, though. A page that submits POST data should have a form and a submit button.
I believe you, but why? Going to run into problems with some browsers?

This works ok.

Code:
 renderFileUpload() {
131     if (this.state.showFileUpload) {
132       return (
133         <div>
134         <font color='white'>Upload new pic</font><br />
135       <input type="file" onChange={this.handleFileChange}/>
136       <button onClick={this.handleUpload}>Upload</button>
137         </div>
138       );
139     }
140   }
Code:
handleUpload = () => {
 46
 47     if (!this.state.selectedFile) {
 48       this.setState( { warning : 'No file selected' } );
 49       return;
 50     } else {
 51       this.setState( { warning : null } );
 52     }
 53     const fd = new FormData();
 54     fd.append('file', this.state.selectedFile, this.state.selectedFile.name)    ;
 55     fd.append('caption', this.state.caption);
 56     fetch( this.props.DATA_URI + '/upload_image', {
 57       method: 'POST',
 58       headers: {
 59         'Accept': 'application/json',
 60       },
 61       credentials : 'same-origin',
 62       body: fd
 63     })
 64     .then((response) => response.json())
 65     .then((data) => {
 66       this.setState( {
 70         showFileUpload : false,
 71         showCaption : true,
 72         showPreview: true,
 73         imageId : data.image_id,
 74         imagePath : data.imagePath,
 75       } );
 76     })
 77     .catch((error) => {
 78       this.setState( { warning : 'There was a problem uploading the file' }    );
 79     });
 80   }

Last edited by microbet; 01-30-2019 at 09:16 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:13 PM
That's from the app I'm doing on the side for myself and it's a React frontend and Python backend and I haven't exactly decided where and when I have javacript camelCasing or pythonic_underscoring and there are some inconsistencies. Note image_id comes back from the Python and I make it imageId in javascript, but I neglected to treat imagePath the same way.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:26 PM
Yeah you might run into issues on not having a form tag and not really submitting a form, even if the browser is just submitting the form to itself.

For one thing it won't work with dropdowns, checkboxes or radio buttons - as there's a whole lot of logic the browser does to turn those into name/value pairs before sending to the back end. With your method you have to replicate all that logic yourself. Also sometimes there are some sensitivity issues with collecting the input before a user clicks submit.

Here's how you can do it with a form tag and a real submit:

Code:
  handleSignup = async (event) => {
    event.preventDefault();
    const data = new FormData(event.target);

    const signupData = {
      username: data.get('email'),
      password: data.get('password'),
      changePassword: data.get('confirmPassword'),
    };

    if (!this.validateForm(signupData)) {
      this.setState({pwdError:true});
      return;
    }
   
   ... do your other stuff here ...

  }
Although I'm not sure FormData is 100% supported yet. But there's a shim if you need to support IE-8 or w/e.


Then in your form:

Code:
            
<form onSubmit={this.handleSignup}>
  <div className="registration">
    <div>
      <label>Email Address / Phone Number</label>
      <input type="text" name="email"/>
    </div>
    <div>
      <label>Create Password</label>
      <input type="password" name="password"/>
    </div>
    <div className="reg-Confirm-password">
      <label>Confirm Password</label>
      <input type="password" name="confirmPassword"/>
    </div>
      {this.state.pwdError && 
    <div className="reg-password-error">
      <strong className='pwd-err-msg'>Please Enter Correct Password</strong>
    </div> }
    <div>
      <button type="submit">CONTINUE</button>
    </div>
  </div>
</form>

Last edited by suzzer99; 01-30-2019 at 09:31 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:37 PM
If no form tag causes some bugs then it is better sure, but having to preventDefault to avoid a page reload? (mostly why people use React?) If that's necessary then not submitting the form and handling it with the onClick seems more straightforward. ??
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:40 PM
Because it's the correct semantics. Various applications expect it. For example, the password vault application LastPass has trouble inferring what fields it should be using for username/password if they're not on a form with a submit button.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 09:48 PM
Quote:
Originally Posted by suzzer99
I think he's just copying and pasting. But yeah the clue level is very low.

Sooooo - since I've now inherited this thing, I have a somewhat noobish react question. We're using BrowserRouter and wrapping our components with withRouter - I think just so we can use props.history.push to route. Might change that but that's not the question.

The question is I have a common behavior that happens after successful login or sign up - we need to go to the back end CRM system, see if we can find the user, and route them to one page if they have a CRM ID and a different page if they don't. There are also other edge cases that get routed to other pages. Because of the vagaries of Cognito and how it integrates with the browser, I cannot just get this info from the back end when the user signs up. It has to be in a separate call.

So obviously I want to consolidate this behavior somewhere and share it amongst all the different ways and places a user can login or sign up.
  1. I could pass the props object to my service that looks up the CRM ID, and have it do the routing. But that doesn't seem like something a service should do.
  2. I could go vanilla old school and just make some shared utility method.
  3. I could wrap the components in some more global component that has a method I can call to do the post login behavior/routing.
  4. Or I could have something at the global state that gets triggered when I do something like setState({userLoggedIn: true});

The last seems like the most react-y way to do things. But it also bugs me in code when magic happens like that. How do I trace what's supposed to happen when userLoggedIn = true triggers something? Seems painful.

Edit: I thought of a 5th way that I might like. Redirect to a SignUpSuccess page that is just a spinner. That page makes the call to the back end and figures out where to route the user. Hmmm.
I like 2, a shared utility method. Seems simple and straightforward.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 10:02 PM
ugh

First off yes that dude's code itself is ****ing awful.

But the "right" way to do form submittal is what you said, a form tag with a submit button. Form tags will also automatically "onSubmit" when you hit enter on inputs inside of it. This is always handled with react not old school "form form" submits. Have a submit function that handles both onClick of a submit button and onSubmit from the form tag.

As far as the react-router question I don't get it - on 200 response from your request to auth them you should have a callback that changes some state/updates redux, and routeProps.history.push, why do you need that more than once?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-30-2019 , 10:14 PM
Also massive leak if you're writing most of your own html/jsx in 2019.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-31-2019 , 12:58 AM
Who's supposed to write my html/jsx?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-31-2019 , 01:04 AM
Quote:
Originally Posted by Grue
ugh

First off yes that dude's code itself is ****ing awful.

But the "right" way to do form submittal is what you said, a form tag with a submit button. Form tags will also automatically "onSubmit" when you hit enter on inputs inside of it. This is always handled with react not old school "form form" submits. Have a submit function that handles both onClick of a submit button and onSubmit from the form tag.

As far as the react-router question I don't get it - on 200 response from your request to auth them you should have a callback that changes some state/updates redux, and routeProps.history.push, why do you need that more than once?
Successful Cognito login can be achieved from the sign in page, the verify account page (after signing up), the google, facebook or internal SAML components. Only after that happens can I call back to our CRM system/local Dynamo DB to see if this user is associated with a real CRM account (or if not try to look them up). So I need to trigger this same business logic from within the success handler of 5 different components.

Once that is done there are 4 or 5 pages (components in the SPA, but basically separate pages from the user's POV) the user can be routed to based on the results (we're also doing weird checking for dupes in Cognito that's super complicated and confusing - but the front end mostly doesn't care about that).

I ended up just creating a utility method with the business logic that calls a separate getUser service to the back end. All I need to pass is props (so props.history.push can be called) and Auth (the AWS Amplify Cognito Auth object). Auth is needed to get the idToken to authenticate the API call and identify the Cognito user to the back end and it also handles all the browser<->Cognito stuff.

Last edited by suzzer99; 01-31-2019 at 01:15 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-31-2019 , 01:23 AM
That sounds fine other than props != routeProps, routeProps is the argument passed to render in react-router-dom but yeah I'm sure you know, I'm a stickler etc.

Quote:
Who's supposed to write my html/jsx?
Much more competent people than me who do all the a11y stuff i.e. material-ui, antd, semantic-ui, whatever. I don't do much "real" html/jsx stuff at all lately, I import components that handle that and then don't have to worry about other nonsense.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-31-2019 , 01:25 AM
I don't know what any of that means. But we have a crappy react dev/CSS guy who I'm basically stepping in for because he's so terrible. So he's definitely not doing any of that.

We do have a good react guy and CSS person - but they're swamped on another project. I can at least go to him for advice and bounce ideas.

Also we're using BrowserRouter and it's surprisingly hard to pass props from say App.js to the Routes themselves. The withRouter HOC seems to at least provide the history API we're using to do in-app routing. But maybe all of that stuff isn't the right choice.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote

      
m