Simple React App-QR Generator

Fnu Tsering Norbu
5 min readJul 29, 2020

--

Can’t believe we made this far in just 12 weeks at Flatiron School from almost no coding experience to competent full stack developer!

This is QR-Code generator React app and here i will go through what i did and how did in this simple project, and you are free to use my GitHub repo down here! This idea came out during barnstorming with my mod 4 project partner Chaya Greisman . We decided not to develop our project around this idea, but i thought it’ll fun if i could do this, it was easy!

https://github.com/Calls4ever/QR-code-Generator

1. React Environment Setup

Using your terminal, you can change directory to the folder where you want your project be and run npm create-react-app <your-app-name> in your terminal and run npm install and then run npm start to see if the app is running in the browser! After the all setups, the file structures will look like this.

react app file structure

2. Database Set Up

Usually we i use rails as back-end but for this simple project, we will create a file callled db.json and will run json-server — — watch db.json which will serve in mostly in localhost:3000/userDetails if you are not using this port. And db.json will look like this.

{  
"userDetails":
[
]
}

3. Structuring Files

It’s up to you however you gonna structure components, but still there are some conventions that i have no idea! Here by default the index.html file will render index.js and index.js will then render App.js and so on. I have divided this app into one container and two components, the QrContainer.js will render it’s components i.e DisplayQr and UserDetailsForm

4. Writing codes in components!

This is what it looks like in app.js

import React from 'react';import './App.css';
import QrContainer from './containers/QrContainer';
function App() {
return (
<div>
<QrContainer />
</div>
);
}
export default App;

This is in container/QrContainer.js

import React from 'react'
import UserDetailForm from '../components/UserDetailsForm'
import DisplayQr from '../components/DisplayQr'
class QrContainer extends React.Component{
state={userDetails: []}
componentDidMount(){ fetch('http://localhost:3000/userDetails') .then(res=>res.json())
.then(userDetails=>{
this.setState({userDetails})
})
.catch(error=>console.log(error))
}
renderUserDetails=()=>{
return this.state.userDetails.map(user=> <DisplayQr {...user} handleDelete={this.handleDelete}/>
)}
serialize = (obj)=> {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); }
return str.join("&");
}
getQrCode=(userDetails)=>{
let data= this.serialize(userDetails)
let qrCode=`http://api.qrserver.com/v1/create-qr-code/?data=${data}&size=200x200`
fetch('http://localhost:3000/userDetails', {
method: "POST",
headers: {
'content-type': 'application/json',
accept: 'application/json'
},
body: JSON.stringify({
qrCode: qrCode,
firstName: userDetails.firstName,
lastName: userDetails.lastName,
telephone: userDetails.telephone,
email: userDetails.email,
dob: userDetails.dob
})
})
.then(res=>res.json())
.then(newUserDetail=>{
this.setState({userDetails: [...this.state.userDetails, newUserDetail]})
})
}
handleDelete=(id)=>{ fetch(`http://localhost:3000/userDetails/${id}`, {method: "DELETE"}) this.setState({userDetails: [...this.state.userDetails.filter(user=> user.id!==id)]})
}
render(){
console.log(this.state.userDetails)
return(
<>
<h1 id='heading-logo' className='display-1' >QR Generator</h1>
<UserDetailForm getQrCode={this.getQrCode}/>
<div className='card-display'>
{this.renderUserDetails()
</div>
</>
)
}}export default

Quick notes on above code snippet, there are few functions,

  1. renderUserDetails: this function will map trough the user details existing in the state above and returns an array of DisplayQr component with props of user details.
  2. serialize: it will take an object of userDetails we get from form and compile them into uri format and returns back; we need this format to get the QR code from the http://goqr.me/api/ as they mentioned in the documentation
  3. getQrCode: it’s name is not what it meant, it does post request to our back-end AKA localhost:3000/userDetails with user details we get from the form and QR Code we got from the API; getting QR code from the API is very simple as you will see in the code. just one line!!
  4. handleDelete: And finally we have handle delete which will make a “DELETE” request to our backend and will set the state so the DOM content will be re-rendered and changes will be seen without refresh!

Note: componentDidMount(); whatever we do in this function will be executed as soon as the component is loaded, so that we don’t have to do anything to load data form backend

In components/UserDetailsForm.js,

import React from 'react'
class UserDetailForm extends React.Component{
state ={
firstName: '',
lastName: '',
telephone: '',
email: '',
dob: ''
}
handleSubmit=e=>{
e.preventDefault()
this.props.getQrCode(this.state)
this.setState({
firstName: '',
lastName: '',
telephone: '',
email: '',
dob: ''
})
}
handleChange=e=>{
this.setState({[e.target.name]: e.target.value}) }
render(){
const {firstName, lastName, telephone, email, dob}=this.state
return(
<form className='user-details-form'
onSubmit={this.handleSubmit}>
<div className="form-row">
<div className="form-group col-md-6">
<label for="inputText4">First Name</label>
<input name='firstName'
onChange={this.handleChange}
value={firstName}
type="text"
className="form-control" id="inputText4"/>
</div>
<div className="form-group col-md-6">
<label for="inputText4">Last Name</label>
<input name='lastName'
onChange={this.handleChange}
value={lastName}
type="text"
className="form-control"
id="inputText4"/>
</div>
<div className="form-group col-md-6">
<label for="example-tel-input"
className="col-2 col-form-label">Telephone</label>
<div className="col-10">
<input name='telephone' onChange={this.handleChange}
className="form-control" type="tel" value={telephone}
id="example-tel-input"/>
</div>
</div>


<div className="form-group col-md-6">
<label for="inputEmail4">Email</label>
<input name='email' onChange={this.handleChange} type="email"
value={email} className="form-control" id="inputEmail4"/>
</div>
<div className="form-group col-md-6">
<label for="example-date-input" className="col-2
col-form-label">DOB</label>
<div className="col-10">
<input name='dob' onChange={this.handleChange}
className="form-control" type="date" value={dob}
id="example-date-input"/>
</div>
</div>
<div className="form-group col-md-4">
<button type='submit' className='btn btn-success btn-large'>
Generate QR for me!</button>
</div>
</div>
</form>
)
}
}
export default UserDetailForm

Quick Note: In the above snippet we don’t have nothing crazy, we only have two functions, one sets the state as per the data we get from form and other; the handleSubmit gets called when we click Generate QR for me button this calls getQrCode function we defined in QrContainer.js file and then sets the state to default to clear the form. Note that form is fully controlled?? Clap this article if you notice it!

And finally we have components/DisplayQr.js

import React from 'react'
const DisplayQr=(props)=>{
return(
<div id='user-details-card'
className="card" style={{width: "20rem"}}>
<img src={props.qrCode} className="card-img-top" alt="..."/>
<div className="card-body">
<h5 className="card-title">{`${props.firstName}
${props.lastName}`}</h5>

<p className="card-text">Phone: {props.telephone}</p>

<p className="card-text">Email: {props.email}</p>
<p className="card-text">DOB: {props.dob}</p>

<a href="#" onClick={()=>props.handleDelete(props.id)}
className="btn btn-danger">Delete</a>
</div>
</div>
)
}

export default DisplayQr

Quick Note: There is nothing much happening here, no functions, only we are doing is rendering the user details we get from the QrContainer as props and rendering them respective jsx! Thats all!

5. Styling!

Don’t ask me how did you do the stylings, i used bootstrap and don’t for get to include
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

in your index.html to use bootstrap, and for extra stylings, i have App.css down here!

.user-details-form{display: flex;margin: 20px;border: solid 1px gray;padding: 20px;box-shadow: 5px 5px 7px 5px rgb(233, 126, 126);border-radius: 2%;}#heading-logo{color: purple;display: flex;justify-content: center;font-family: Orbitron , sans-serif;}.card-display{display: flex;flex-wrap: wrap;margin: 30px;border: solid 2px rgb(233, 126, 126);box-shadow: 5px 5px 7px 5px rgb(233, 126, 126);}#user-details-card{border: solid 3px rgb(233, 126, 126);margin: 10px;border-radius: 5%;}

Enjoy Coding!

spoiler alert, the app will work like this!

Thanks for the claps!

--

--