July 26

Full Stack: ToDo App with MySQL, Node.js, Express and React

So I had two goals for this summer, Build a full stack app and make a React Native app. Using a stack of MySQL, Node.js, Express and React I managed to build a full stack ToDo app! In this blog post I’ll show you how I did it!

The whole app works like this: I have a MySQL database where I store all my ToDos. Using Node.js and Express (a web application framework) I made a REST API that will allow my React front end to communicate with the MySQL database. And, of course, React as the front end.

Here’s how the React front end app ended up looking!

So, for the SQL server I could use either MySQL or MongoDB. I decided to use MySQL since I already have a lot of experience with it through school. MySQL is maintained by Oracle, and is both open-sourced and free to use! MySQL runs in the background of your computer and you can give it commands through the CMD to manage your database, but I strongly recommend downloading MySQL Workbench so you can get a nice GUI to use instead. I won’t go into depth about how I made my database here.

The ToDo table from MySQL Workbench

Now, for the API I decided to use Node.js and Express. They are also both free to use and very popular. For those that don’t know, Node.js is JavaScript runtime built using Chrome’s V8 JavaScript Engine. Basically, JavaScript usually only runs through a browser, but with Node.js we can run it without one. Express is a web app framework for Node.js. It makes creating APIs so much easier.

So first up is the entry point “server.js” file:

// Init
const express = require('express');
const bodyParser = require("body-parser");
const cors = require('cors');

// Set up a const for express and a port
const app = express();
const port = 3000;

// Init connection to database
const db = require('./db');

// Middleware
app.use(cors());
app.use(bodyParser.json());

// Routers
const todoRouter = require('./routes/todo.route');

// Use routers
app.use('/todo', todoRouter);

// Start listening/server
app.listen(port, () => console.log(`ToDo API listening on port ${port}...`));

First I import express itself, body-parser (used for taking the body information from a POST and making it accessible for the API) and CORS (which is used for being able to skip the Same-origin policy, which means we can connect with remote hosts to the API). Next is setting up express and a port to use with it. After that I set up something called “Middleware”. They are basically functions that gets called when the API receive a request and can manipulate the request object from the user and the response object from the API. We have to set both cors and body-parser as middleware for them to work. Next, I set up “routers” for my todos. I need to research routers a little more, but they let me organize my routes into a different file.

For connecting the API to my database I have a file called “db.config.js” which handles the settings:

module.exports = {
  HOST: "localhost",
  USER: "root",
  PASSWORD: "PASSWORD",
  DB: "tododb"
};

And then a “db.js” for connecting to the database:

const mysql = require("mysql");
const dbConfig = require("./config/db.config.js");

// Create a connection to the database
const connection = mysql.createConnection({
  host: dbConfig.HOST,
  user: dbConfig.USER,
  password: dbConfig.PASSWORD,
  database: dbConfig.DB
});

// open the MySQL connection
connection.connect(error => {
  if (error) throw error;
  console.log("Successfully connected to the database!...");
});

module.exports = connection;

Here I just create a connection using a MySQL library for Node.js, and export it so that the route files can use it.

Last up is the route file for ToDo. This is the code that’s gonna handle the HTTP request and responses for the ToDos. I’m not gonna show the entire file since it’s quite big, but all of the functions looks quite the same. It can be viewed through the GitHub page.

const express = require('express'),
    router = express.Router(),
    db = require('../db');

// Get one ToDo
router.get('/:todoId', function (req, res) {
    let sql = `SELECT * FROM todo WHERE id = ${req.params.todoId}`;

    db.query(sql, function (err, data, fields) {
        if (err) return res.status(400).send(err);

        if(Object.keys(data).length === 0) return res.status(404).send(`404: ToDo with id: ${req.params.todoId} not found.`);

        res.json({
            data,
            message: "ToDo retrieved successfully"
        })
    });
});

First, I’m importing express, the router and the db (database connection). I can now add functions that handles “Get”, “POST”, “Put” and “Delete” requests for my ToDos. In the code above I handle a Get request for getting a single specific ToDo from the database. Using “db” I can send a query to my database and use it in the callback function. From the callback function I can check if it’s empty (and in case return a HTTP status code 404: Not found) or send the data it found as a JSON object back to the React client.

And that’s it for the back-end. My API isn’t the best right now, but I’m planning to add JWT security and rewrite it so that it uses the information from the body of an HTTP request.

Now for the front-end. I’ve covered making React apps some times now, so for this blog post I’m only gonna focus on what’s related to the full-stack part.

First, in my constructor I add a var for my API Url:


  constructor(props) {
    super(props)

    this.apiURL = "http://localhost:3000";

    this.state = {
      todos: []
    }
  }
Then when my App starts I run a function called "getTodos" which sends a HTTP request to my API and (hopefully) receives some ToDos back, and sets the state:


// When the app starts, get todos from the database and set it to the state
  componentDidMount() {
    this.getTodos();
  }

  getTodos() {
    fetch(`${this.apiURL}/todo`)
      .then(res => res.json())
      .then((data) => {

        let todos = data.data;

        // Convert 'completed' from 0's to bools
        for (let i = 0; i < todos.length; i++) {
          todos[i].completed = (todos[i].completed === 0) ? false : true;
        }

        // Set todos in the state
        this.setState({ todos })
      })
      .catch(console.log)
  }

Since MySQL doesn't support straight up boolean values, I use 0's and 1's as false and true. That's why I convert the "completed" value from those 0's and 1's to bool's.

Now for adding a new ToDo:


  // Adds a new ToDo
  addToDo = desc => {
    fetch(`${this.apiURL}/todo?desc="${desc}"&completed=0`, { "method": "POST" })
      .then(res => res.json())
      .then((data) => {

        //Refresh ToDos
        this.getTodos();

      })
      .catch(console.log)

  }

I send a POST request with the new ToDos description in the query and a completed value of zero. The id is being set server side, so my client app doesn't need to set it itself. In the callback function I could receive the id back and just add a new ToDo object to my array, but I decided to take the lazy way and just refresh all ToDos from my database.

The delete and update (setAsComplete) functions are quite similiar:


// Marks a ToDo as completed
  setAsCompleted = id => {
    // Get the selected todo
    let editedToDo = this.state.todos.find(todo => todo.id === id);

    // Flip the completed value and return it as a number
    editedToDo.completed = editedToDo.completed ? 0 : 1;

    fetch(`${this.apiURL}/todo?id=${editedToDo.id}&desc="${editedToDo.desc}"&completed=${editedToDo.completed}`, { "method": "PUT" })
      .then(res => res.json())
      .then((data) => {

        //Refresh ToDos
        this.getTodos();

      })
      .catch(console.log)
  }

  // Removes ToDo
  removeToDo = id => {
    fetch(`${this.apiURL}/todo/${id}`, { "method": "DELETE" })
      .then(res => res.json())
      .then((data) => {

        //Refresh ToDos
        this.getTodos();

      })
      .catch(console.log)
  }

And that's it! A full working full-stack ToDo application!

This image has an empty alt attribute; its file name is image-8.png

My next plan is to port over my client React app to React Native, so stay tuned for that!

July 20

Periodic Table with React

Hi again! So when I was working on my calculator I realized I needed more practice with CSS, especially grids. While researching I came across this blog post, where they make a Periodic Table with React. I felt inspired to do the same. It would be a nice way to practice on my CSS skills! Apologies for the short blog post, since I’m on a little time crunch here!

I planned my app to work like this: It would show all of the elements like the Periodic Table, and if you hover over one them it will show an info screen at the bottom. The data would be imported through a JSON file which was created by “Bowserinator” and can be downloaded from his GitHub page. This is how to final product looks like:

Making the React components themselves was an easy task. I first created an “Element” component that got it’s element number as a prop, and then loads the corresponding element data from the JSON file.


export class Element extends Component {

    constructor(props) {
        super(props)

        //Make sure it's not the '57-71' or '89-103'
        if (!props.notElement) {

            //Get the right element data from the JSON file
            let element = dataFile.elements.filter(e =>
                e.number === props.nr
            );

            //Set the data
            this.state = {
                element: element[0]
            }
        }
    }


    render() {
        if (!this.props.notElement) {
            // Show element
            const { element } = this.state;

            return (
                <div className={`component-element element-${element.number} ${element.category}`} onMouseOver={() => this.props.handler(element)}>
                    <div className="number">{element.number}</div>
                    <div className="symbol">{element.symbol}</div>
                </div>
            )
        } else {
            // Show '57-71' or '89-103'
            return (
                <div className={`component-element short${this.props.nr}`}>
                    <div className="number">{this.props.nr}</div>
                </div>
            )
        }
    }
}

To make the periodic table layout I created a CSS class like this:


  .table-elements {
    display: grid;
    grid-template-columns: repeat(17, auto) 1fr;
  }

First I need to set the display to be grid, and then I create a grid with 18 columns.

Since I’m going to have my Periodic Table with the middle elements by itself under (like most periodic tables do), I had to create an additional grid with 14 rows:


  .table-elements-extra {
    display: grid;
    grid-template-columns: repeat(14, auto) 1fr;

    padding-top: 5%;

    margin-left: auto;
    margin-right: auto;

    width: 80%;
  }

Using margin-left and margin-right I can center the additional grid.

To make sure the elements get positioned correctly I made some CSS classes that set the grid’s column starting point:


.element-2 {
    grid-column-start: 18;
}

.element-5, .element-13 {
    grid-column-start: 13;
}

The number corresponds to the element number. Since I have:


<div className={component-element element-${element.number} ${element.category}}

in my Element component, it automatically applies the correct CSS class to the elements with the number. I also use category for setting the elements background color.

In my App component I create several list’s with just numbers in them:


  constructor(props) {
    super(props)

    this.createElements();

    this.state = {
      selectedElement: null
    }
  }

  createElements() {
    this.elements_1To56 = [];
    this.elements_57To71 = [];
    this.elements_72To88 = [];
    this.elements_89To103 = [];
    this.elements_104To118 = [];

    for (let i = 1; i <= 56; i++) this.elements_1To56.push(i);
    for (let i = 57; i <= 71; i++) this.elements_57To71.push(i);
    for (let i = 72; i <= 88; i++) this.elements_72To88.push(i);
    for (let i = 89; i <= 103; i++) this.elements_89To103.push(i);
    for (let i = 104; i <= 118; i++) this.elements_104To118.push(i);
  }

The reason I do several lists is because I have to divide the table into multiple parts. This makes it easier to create the table.

To render them I have to use the map function to iterate through the lists:


render() {

    return (
      <div className="wrapper">

        <h1>Periodic Table</h1>

        <div className="table-elements">

          {/* Elements 1 - 56 */}
          {this.elements_1To56.map((element, index) => {
            return <Element handler={this.setActiveElement} key={element} nr={element} />
          })}

          <Element nr="57-71" notElement />

          {/* Elements 57 - 71 */}
          {this.elements_72To88.map((element, index) => {
            return <Element handler={this.setActiveElement} key={element} nr={element} />
          })}

          <Element nr="89-103" notElement />

          {/* Elements 104 - 118 */}
          {this.elements_104To118.map((element, index) => {
            return <Element handler={this.setActiveElement} key={element} nr={element} />
          })}

        </div>

        <div className="table-elements-extra" >
          {/* Elements 57 - 71 */}
          {this.elements_57To71.map((element, index) => {
            return <Element handler={this.setActiveElement} key={element} nr={element} />
          })}

          {/* Elements 89 - 103 */}
          {this.elements_89To103.map((element, index) => {
            return <Element handler={this.setActiveElement} key={element} nr={element} />
          })}
        </div>

It looks a little ugly, but it’s a lot better than having 118 lines for each element.

Last, I want to have a Info bar at the bottom that shows info about the element that’s currently being hovered over. The component takes an Element object, that has the data from the JSON file, as a prop.


export class InfoBar extends Component {
    render() {
        if (this.props.element !== null) {
            const { element } = this.props;

            return (
                <div className="info-bar">

                    <div className="element-short-info-container">
                        {/* Show element box */}
                        <div className={`component-element big ${element.category}`}>
                            <div className="number-big">{element.number}</div>
                            <div className="symbol-big">{element.symbol}</div>
                        </div>

                        <div className="element-mass">Mass: {element.atomic_mass}u</div>
                        <div className="element-electron">Category: {element.category}</div>
                    </div>

                    {/* Element name */}
                    <div className="element-info-container">
                        <div className="element-name">{element.name}</div>
                        <div className="element-desc">{element.summary}</div>
                    </div>
                </div>
            )
        } else {
            return <div> </div>
        }
    }
}

The last thing to do is add a hover handler for our elements in our App component that I will pass down to the elements as a prop:


  setActiveElement = element => {
    this.setState({
      selectedElement: element
    })
  }

And it’s done!

I’m really happy about how the project ended up. I got to practice the things I needed and learned a lot more about CSS and styling. I can already feel that I’m getting a lot more confident with React as well, since the project only took so little time to make. Most of it went into learning CSS.

Here’s the link to the GitHub page! I’m also gonna research how I can upload live demos from my demos!

Thanks for reading!

Category: ReactJS | LEAVE A COMMENT
July 16

Calculator with React Pt. 2:

So, I’ve made some huge changes since part 1. Since I’ve redesigned how the calculator looks and how it works, I’ve decided to just make a blog post about the finished calculator and how it works. Code is available on Github.

So first I needed to make it look better. Even though I think we all can appreciate that good ol’ Windows 98 look, it needed to be better. So this is how it looked before:

Animated GIF

And this is how it looks now! Even got a division button!

I won’t go into depth about how I made it look like that, but the CSS files are available on the GitHub page!

So let me show you how I made this!

First I make a state in my main App:


export default class App extends React.Component {

  constructor(props) {
    super(props)

    this.state = {

      isNumber1: true,
      number1: "0",
      operator: "",
      number2: "0"

    }
  }

I’m going to use the “isNumber1” bool to check if the user is inputting on the first or second number. “number1” and “number2” is for holding our input numbers and operator is for deciding what operation we are gonna do.

The “Button” component I created in part 1 is still mostly the same. I only added support for orange color and made the render function return only the button, so the the CSS grid would work with my buttons. I use the CSS grid to layout my buttons. Here’s the “Button” component:

Full code for Button component

import React, { Component } from 'react'
import propTypes from 'prop-types'
import './Button.css';

class Button extends Component {

    constructor(props) {
        super(props);

        this.buttonValue = props.buttonValue;

        //Set Button styling
        let p = props;

        this.className = "component-button";

        //Wide or small
        if (p.wide) {
            this.className += " wide"
        } else if (p.small) {
            this.className += " small";
        }

        //Colors
        // eslint-disable-next-line default-case
        switch (p.color) {
            case "blue":
                this.className += " blue";
                break;

            case "red":
                this.className += " red";
                break;

            case "orange":
                this.className += " orange";
                break;

        }

    }

    render() {
        return <button className={this.className} onClick={() => this.props.clickHandler(this.buttonValue)} >{this.buttonValue}</button>

    }
}

// Prop types
Button.propTypes = {
    wide: propTypes.bool,
    color: propTypes.string
}


export default Button

[collapse]

In part 1 I made a main clickHandler that I passed to every Button component, and it just decided what other handler to call depending on the button value it recieved. But I figured, why do that? I can just pass the correct clickHandler as a prop to the different Button components. That way it’s both cleaner, easier and I get rid of an entirely useless function.

I also changed how I added numbers to the calculator. Before I would multiply the current number with 10 and add whatever button value that was pressed, but since this is JavaScipt (a loosely typed language) I can just treat the number as a string until I need to do any calculation with it! Because of that, I can just add the button value as a string to the number. Easy! I also refactored how I check which number to add it to, by using a ternary operator and a new trick I found for the “setState” function.


  addNumber = number => {

    // Decide which number should be changed
    let changeNumber = this.state.isNumber1 ? "number1" : "number2";

    let newNumber = 0;

    // Check if a zero should be replaced by a number
    if (this.state.isNumber1) {
      newNumber = (this.state.number1 === "0") ? number.toString() : this.state.number1 + number.toString();
    } else {
      newNumber = (this.state.number2 === "0") ? number.toString() : this.state.number2 + number.toString();
    }

    // Change number
    this.setState({
      [changeNumber]: newNumber,
    });

  }

As you can see, I also check if the number is only a zero, and if it should be replaced by a number.

Next up, the click handlers for the operator buttons and AC. These are simply just setting the state of the App.


// Set the operator
  setOperator = operator => {
    this.setState({
      operator,
      isNumber1: false
    });
  }

  // AC Button - All Clear
  allClear = () => {
    this.setState({
      isNumber1: true,
      number1: "0",
      operator: "",
      number2: "0"
    });
  }

For adding the ability to add a decimal I can mainly do the same thing I did for adding a number, just add a “.” behind the number. I also make sure to check if there’s any periods in the number beforehand, and then in-case exiting the function.


  // Adds a "." to the number
  addDecimal = number => {

    // Decide which number to change
    let changeNumber = this.state.isNumber1 ? "number1" : "number2";

    // If the number already contains a '.' then just exit the function
    if (this.state.isNumber1) {
      if (this.state.number1.includes('.')) return;
    } else {
      if (this.state.number2.includes('.')) return;
    }

    // Get the new number to set
    let newNumber = this.state.isNumber1 ? this.state.number1 + "." : this.state.number2 + ".";

    // Set the number
    this.setState({
      [changeNumber]: newNumber
    });
  }

To make the Backspace click handler, I use substring (remember, I treat numbers as string) to get a new string without it last’s char.


  removeLast = () => {
    let number = this.state.isNumber1 ? this.state.number1 : this.state.number2;
    let changeNumber = this.state.isNumber1 ? "number1" : "number2";

    //Make a new number without the last char/number
    number = number.substring(0, number.length - 1);

    //Update the state
    this.setState({
      [changeNumber]: number
    });

  }

The equal button click handler is quite simple:


  //Solves the equation
  equals = () => {
    let operator = this.state.operator;

    let number1 = Number(this.state.number1);
    let number2 = Number(this.state.number2);
    let answer = 0;

    if (operator === "+") {
      answer = number1 + number2;
    } else if (operator === "-") {
      answer = number1 - number2;
    } else if (operator === "x") {
      answer = number1 * number2;
    } else if (operator === "/") {
      answer = number1 / number2;
    }

    this.setState({
      isNumber1: true,
      number1: answer.toString(),
      operator: "",
      number2: "0"
    });

  }

All the click handler’s are done. Now we need a number screen to show what’s happening. For this, I made a “NumberScreen” component which takes in the two numbers and the operator as a prop, and show’s it in the render function.


class NumberScreen extends Component {
    render() {
        //Destructering
        const { number1, operator, number2 } = this.props;

        //if number2 doesn't contain anything other than zero, don't show it
        let displayValue = (number2 === "0") ? number1 + operator : number1 + operator + number2;

        return (
            <div>
                <input className="number-screen" disabled value={displayValue} />
            </div>
        )
    }
}

Last, we just need to put the pieces together in our App’s render function:


render() {
    return (
      <div className="calculator">

        <p className="logo-text">My React Calculator</p>
        {/* Number Screen */}
        <NumberScreen number1={this.state.number1} operator={this.state.operator} number2={this.state.number2} />

        <div className="calculator-buttons">
          {/* Row 5 */}
          <Button buttonValue="AC" clickHandler={this.allClear} wide color="red" />
          <Button buttonValue="←" clickHandler={this.removeLast} color="red" />
          <Button buttonValue="/" clickHandler={this.setOperator} color="orange" />

          {/* Row 4 */}
          <Button buttonValue="7" clickHandler={this.addNumber} />
          <Button buttonValue="8" clickHandler={this.addNumber} />
          <Button buttonValue="9" clickHandler={this.addNumber} />
          <Button buttonValue="x" clickHandler={this.setOperator} color="orange" />

          {/* Row 3 */}
          <Button buttonValue="4" clickHandler={this.addNumber} />
          <Button buttonValue="5" clickHandler={this.addNumber} />
          <Button buttonValue="6" clickHandler={this.addNumber} />
          <Button buttonValue="-" clickHandler={this.setOperator} color="orange" />

          {/* Row 2 */}
          <Button buttonValue="1" clickHandler={this.addNumber} />
          <Button buttonValue="2" clickHandler={this.addNumber} />
          <Button buttonValue="3" clickHandler={this.addNumber} />
          <Button buttonValue="+" clickHandler={this.setOperator} color="orange" />

          {/* Row 1 */}
          <Button buttonValue="0" wide clickHandler={this.addNumber} />
          <Button buttonValue="," clickHandler={this.addDecimal} />
          <Button buttonValue="=" clickHandler={this.equals} color="blue" />

        </div>
      </div>
    );
  }

As I said earlier, it would be better to have the buttons in it’s own component for organizing and just better programming, but it works for this little project.

And that’s it! I’m really happy about how this project turned out, but I do have some regrets. The biggest one being how I’m deciding what number to add to. I think I could have come up with a better way to deal with that, but that will have to be for another time!

Thanks for reading!

GitHub Link

Category: ReactJS | LEAVE A COMMENT
July 13

Sudoku Solver with React

Hi again! So I was on a cabin trip this weekend, and after solving countless amount of Sudoku I thought: “Hey, I could port over one of my old Sudoku Solver projects to React!”. I made one previous in C#, but the interface was just a terminal (“Ew…” I know). With React being made for creating UIs this proved to be a perfect project!

Usually I create the blog post while I’m making the projects, but this time I made the application first. So I won’t be going so in-depth in this blog post on how to make it, but the code will however, as always, be available!

So this is how the “Sudoku Solver” looks like:

Just enter the unsolved Sudoku into the cells, hit the “Solve” button… and voila!

This is how I made it:


class App extends Component {

  constructor(props) {
    super(props)

    //Set our sudoku size
    this.width = 9;
    this.height = 9;

    this.state = {
      board: this.createBoard(this.width, this.height),     //Our sudoku board
      invalidSudoku: false                                  //If the sudoku in the board is valid
    }

  }

First making it so that the “App” has a state with two variables. One for the board (2D Array) and one for if the input Sudoku is valid (bool). “createBoard” just returns a 2D Array (an array with arrays) with 0’s.

Next I made a handler for when one of the numbers in a “Cell” (where the user can put in a number) changes:


  //Changes the value in the state board
  changeValue = (i, j, num) => {

    //Create a copy of our current board
    let newBoard = this.state.board;
    newBoard[i][j] = num;

    //Update our state with the new board
    this.setState({
      board: newBoard,
      invalidSudoku: false                  //Since the sudoku changed we can set invalid to be false
    }, () => {
      this.setState({ state: this.state }); //Force a re-render after it's done with setting the state
    });
  }

Here I take three vars. “i” and “j” to know which spot we are changing, and the “num” put in. When you change the state in React, you have to use the “setState” method, so that React knows that it has to re-render the component. “setState” is done async ,so to show the state change immediately after the change is done we have to use the “setState’s” second parameter to give it a callback function. Setting another “setState” in the callback function will force it to re-render the component after the previous state has been updated. An inefficient (since it re-renders twice now), but good enough trick for this project.

Now if the user clicks the “Submit” button I run this function through the clickHandler:


  solve = () => {

    //Create a solvedBoard from the Solver class. It either returns as an 2D-array or bool
    let solvedBoard = new Solver(this.state.board);

    //If it's an array then it should be a valid solution. Set it as the current board
    if (Array.isArray(solvedBoard)) {
      this.setState({
        board: solvedBoard,
      }, () => {
        this.setState({ state: this.state }); //Force re-render
      });
    }else{
      //If it's not a valid array, then it's not a valid sudoku.
      this.setState({
        invalidSudoku: true                   //Set it as an invalid sudoku          
      }, () => {
        this.setState({ state: this.state }); //Force re-render
      });
    }
  }

I haven’t shown the Solver yet (I will do that after the React stuff), but know that in the constructor it either returns false if it didn’t find a solution or the sudoku is invalid, or a board if it succeeds. If it succeeds then we update the state with the solved board, and force a re-render!

The App’s render function looks like this:


  render() {
    return (
      <div className="App">

        <h1>Sudoko Solver</h1>

        {/* Show a table that shakes if it's an invalid sudoku. Using date as an key so that it shakes every time it re-renders*/}
        <table className={this.state.invalidSudoku ? "shake" : ""} key={new Date()}> 
          <tbody>
            {
              // Loop through the board and render a Cell for every number
              this.state.board.map((row, i) => (
                <tr key={i * 9}>
                  {row.map((cell, j) => <td key={(i * 9) + j + 1}> <Cell changeValue={this.changeValue} i={i} j={j} value={this.state.board[i][j]} /> </td>)}
                </tr>
              ))
            }
          </tbody>
        </table>

        <button className="button-submit" onClick={() => this.solve()}>Solve!</button>

        {/* Render an error message if the sudoku is not valid */}
        {this.state.invalidSudoku ? <h4 key={new Date() + 1} className="text-error">Not a valid sudoku!</h4> : ''}

      </div>
    );
  }

I render the Sudoku board using a table with some CSS (also in the bottom of the post). For every number in the board, I render a Cell component to show and handle the number being changed. I also pass along the clickHandler function “changeValue” to the Cell components. Afterwards I show a “Solve” button and an error message if the Sudoku is not valid.

The “Cell” component looks like this:


import React, { Component } from 'react'
import './Cell.css'

class BtnNumber extends Component {

    changeValue = (event) => {
        //Prevents user from entering a non-number
        if (!Number(event.target.value) && event.target.value !== "") return;

        //Changes the board value
        this.props.changeValue(this.props.i, this.props.j, Number(event.target.value));

    }

    render() {
        return (
            <div>
                {/* Renders the cell. Shows 0 as nothing */}
                <input className='component-btn-number' value={(this.props.value === 0) ? ' ' : this.props.value} onChange={event => this.changeValue(event)} />
            </div>
        )
    }
}

export default BtnNumber

I use an “input” element as a way to both show the number and receive input from the user. I only show a number as long as it’s not zero since empty fields in the Sudoku board is set to be 0. In the “changeValue” I make sure the input can only be a number by simply not setting the value unless it’s a number.

Now for the Solver. To solve an Sudoku I use the “Backtracking algorithm”. Basically what happens is that the app starts in the top-left and tries every number, making sure that it’s valid, until it reaches the bottom-right. The trick about a backtracking algorithm is that if it reaches a dead end, it will track back to a previous state and try a different number.

File:Sudoku solved by bactracking.gif
A visual representation on how backtracking works. Credits to Wikipedia for the gif

We can achieve this by using a “recursive method”. A recursive method is a method that calls itself! I started making my own implementation for the backtracking method, but after some time I decided to reuse the code from my old C# project, since I wanted this project to be about learning about React, not algorithms. The code originally comes from the website https://www.geeksforgeeks.org/sudoku-backtracking-7/ and is made by 29AjayKumar. I won’t go in-depth about the solver, but know that the “solve” function and half of the “isValid” function was made by 29AjayKumar!



class solver {

    constructor(board) {
        this.board = board;

        if (this.isValidSudoku(this.board)) {                       //Check first if the sudoku is valid
            if (this.solve(this.board, this.board.length)) {        //Start the solving process.
                return this.board;                                  //If "solve" returns true, then return the solved board
            } else {
                return false;                                       //Else return false
            }
        }else{
            return false;                                           //If it's not a valid sudoku, return false
        }
    }

    //Original code by 29AjayKumar. Found on https://www.geeksforgeeks.org/sudoku-backtracking-7/
    solve(board, n) {

        let row = -1;
        let col = -1;
        let isEmpty = true;

        //Checks if there's any empty spot left
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                if (this.board[i][j] === 0) {
                    row = i;
                    col = j;

                    isEmpty = false;
                    break;
                }
            }
            if (!isEmpty) {
                break;
            }
        }

        // no empty space left 
        if (isEmpty) {
            return true;
        }

        // else for each-row backtrack 
        for (let num = 1; num <= n; num++) {
            if (this.isValid(board, row, col, num)) {
                this.board[row][col] = num;
                if (this.solve(board, n)) {
                    return true;
                }
                else {
                    // replace it
                    this.board[row][col] = 0;
                }
            }
        }

        return false;
    }

    isValid(board, col, row, num) {
        //Check rows
        for (let i = 0; i < board.length; i++) {
            if (i !== col) { //Dont check own number
                if (board[i][row] === num) return false;
            }
        }

        //Check Y Axis
        for (let i = 0; i < board.length; i++) {
            if (i !== row) { //Dont check own number
                if (board[col][i] === num) return false;
            }
        }

        //Check box. Also by 29AjayKumar
        let sqrt = Number(Math.sqrt(board.length));
        let boxRowStart = col - col % sqrt;
        let boxColStart = row - row % sqrt;

        for (let i = boxRowStart; i < boxRowStart + sqrt; i++) {
            for (let j = boxColStart; j < boxColStart + sqrt; j++) {
                if (i !== col &#038;&#038; j !== row) {
                    if (board[i][j] === num) {
                        return false;
                    }
                }
            }
        }
        
        return true; //Else it must be valid
    }

    isValidSudoku(board) {
        for (let i = 0; i < board.length; i++) {
            for (let j = 0; j < board.length; j++) {
                if (board[i][j] !== 0 &#038;&#038; !this.isValid(board, i, j, board[i][j])) return false;
            }
        }

        return true;
    }

}



export default solver;


And that’s it! I’m really happy about how this project went! I learned more about how to deal with states and props, and just React in general.

Link to the project Github: https://github.com/atle517/React-SudokuSolver

Category: ReactJS | LEAVE A COMMENT
July 9

Calculator with React Pt. 1: Buttons!

So these last past days I’ve been watching a lot of React videos from Codevolution, and I also completed the React + Redux course in the SoloLearn app!

Yet another certificate for my collection!

In my opinion, the best way to learn is to be practical with what you are trying to learn. So I figured I would try to build a simple calculator app with React using what I’ve learned so far!

So in React we use something called “Components”. They are the building blocks of a React app. Components kinda work like functions or a classes in JavaScript, but they can accept input through something called “props”, and they each have their own “state”. Components returns HTML content through a render function. Usually we wanna split code into as many components as possible. That way our code is easier to read and also reusable.

Now our main file to work in is gonna be “src/App.js”. In “App.js” there’s some demo content which comes with React, but we can just remove that. Now we are left with:


import React, { createElement } from 'react';
import './App.css';

export default class App extends React.Component {

  render() {
    return (
      <div className="App">
      </div>
    );
  }
}

First thing we are gonna is to make a Button component! We can choose between a functional component or a class component. Since I haven’t learned about hooks yet, I’m gonna choose class component since I need to be able to set the state. For our props we want to take in what type the button should be, be able to determine if the button should be regular sized or wide, and if it needs a special color. Our constructor ends up looking like this:


    constructor(props) {
        super(props);

        this.buttonValue = props.buttonValue;

        //Set Button styling
        let p = props;

        if (p.wide && p.color === "red") {
            this.className = "component-button wide red";
        } else if (p.wide) {
            this.className = "component-button wide";
        } else if (p.color === "blue") {
            this.className = "component-button blue";
        } else {
            this.className = "component-button";
        }

    }

The props are being automatically sent by React, so all we need to do is to make a constructor which takes props and send them in the super function. We can use some if statements with the props and a variable, “className”, to change which CSS class the button should use for rendering.

Now, for our render function. The render function will be automatically called by React when the component is first created or when it notices that the components props or state has changed. This is actually one of the main features that makes React awesome and very performance effective! Instead of having to refresh the entire DOM (Document Object Model), React creates a Virtual DOM and re-renders only the necessary parts!

Now let me show my buttons render function:


    render() {
        return (
            <div>
                <button className={this.className} onClick={() => this.props.clickHandler(this.buttonValue)}>{this.buttonValue}</button>
            </div>
        )
    }

As we can see it looks like we are returning some HTML content, but there’s also some curly braces with JavaScript in them? This is actually the JSX syntax. With JSX we can write both HTML and JavaScript together! To use variables we just have to write a them inside curly braces. What’s happening in the background is that the JSX code is being transpiled into JavaScript. The code is being transformed into JavaScript using Reacts createElement function. So this means that you can just use the createElement function instead of JSX, but I reeeeeally don’t recommend that. Also note that React uses “className” instead of “class”!

For our clickHandler we are actually using a function that we are gonna create in the “App.js” file. The reason for this is that it’s the easiest way to communicate between a “child” component (the button) and a “parent” component (the “App”). Since we are using JavaScript we can just pass down the function to the child using props, and then set it in the render function! Pretty cool!

I’ve set up some CSS files for our App component and our Button component. I’m not gonna in depth about them, but just know to use CSS with React you have to import the files.

App.css

body {
  background-color: #d6d6d6;
}
[collapse]
Button.css

.component-button {
    width: 25%;
    height: 50px;
    font-family: "Calibri";
    font-size: 1.75rem;
    float:left;
    outline:none;
    
}   

.component-button.wide {
    width: 50%;
}

/* Red button */
.component-button.red {
    background-color: #ff5d5d;
}

.component-button.red:hover {
    background-color: #ff4949;
}

.component-button.red:active {
    background-color: #ff5d5d;
}

/* Blue button */
.component-button.blue {
    background-color: #5d93ff;
}

.component-button.blue:hover {
    background-color: #4a85fc;
}

.component-button.blue:active {
    background-color: #5d93ff;
}
[collapse]

Now, let’s see the buttons! In our “App.js” we import the Button component and then create them in our render function:


import React, { createElement } from 'react';
import './App.css';
import Button from './components/Button';

export default class App extends React.Component {

  clickHandler = buttonValue => {
    //ClickHandler for Button
  }

  render() {
    return (
      <div className="App">
        {/* Row 5 */}
        <Button buttonValue="CE" wide color="red" />
        <Button buttonValue="←" wide />

        {/* Row 4 */}
        <Button buttonValue="7" clickHandler={this.clickHandler} />
        <Button buttonValue="8" clickHandler={this.clickHandler} />
        <Button buttonValue="9" clickHandler={this.clickHandler} />
        <Button buttonValue="x" />

        {/* Row 3 */}
        <Button buttonValue="4" clickHandler={this.clickHandler} />
        <Button buttonValue="5" clickHandler={this.clickHandler} />
        <Button buttonValue="6" clickHandler={this.clickHandler} />
        <Button buttonValue="-" />

        {/* Row 2 */}
        <Button buttonValue="1" clickHandler={this.clickHandler} />
        <Button buttonValue="2" clickHandler={this.clickHandler} />
        <Button buttonValue="3" clickHandler={this.clickHandler} />
        <Button buttonValue="+" />

        {/* Row 1 */}
        <Button buttonValue="0" wide clickHandler={this.clickHandler} />
        <Button buttonValue="," />
        <Button buttonValue="=" color="blue" />
      </div>
    );
  }
}

And now we have a nice calculator layout with some buttons to press!

Animated GIF

And that’s it for this time! I noticed afterwards that the division operator is missing, but I’ll fix that next time!

Category: ReactJS | LEAVE A COMMENT
July 4

Hello, React World!

So I previously said that making a React Native app within the summer is over is my goal. I started with refreshing some of my JavaScript since I know how vital it is when it comes to React. Although I didn’t quite finish my little asteroids game, I feel like I reached my goal. And we are also already in July so it’s time to move on! For learning ReactJS I’m using Codevolution‘s ReactJS tutorial. It seems really good so far!

So, my goal is to create a React Native app, but the tutorials I found all recommended to learn ReactJS first, so that’s what I’m gonna do. For those that don’t know, ReactJS is an open-source JavaScript library created and maintained by FaceBook themself. It’s designed to specifically create User-Interfaces.

Obviously the first thing I have to do is to create a Hello World application! To create a React project I needed to first have Node.js installed. Next, I needed a code editor. I choose VS Code. I also installed a extension called “ES7 React/Redux/GraphQL/React-Native snippets” to get some nice shortcuts.

Now, to create a React project you just need to run “npx create-react-app hello-world” in VS Code’s terminal. Easy! To make our Hello World application, we just need to go into “src/App.js” and edit the code to this:

 
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello, React World!
        </p>
        <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
          Learn React
        </a>
      </header>
    </div>
  );
}

To run it, we just need to run “npm start” in our VS Code Terminal. This opens a browser window with our app. It also auto-refreshes the site anytime we make changes to our app.

And we are done!

Category: ReactJS | LEAVE A COMMENT