Skip to main content

Quickstart: React

Introduction

This article will cover how to code simple CRUD operations in a to-do app using React, and Altogic. You can check out the demo.

What are the features of the to-do app?

  1. Create a to-do

  2. Update to-do status

  3. Delete a to-do

  4. List all to-do’s

Set up the backend

Create App

We can create an app with the Altogic Designer fast. To create an app via the Designer:

  1. Log in to Altogic with your credentials.

  2. Select New app.

  3. In the App Name field, enter a name for the app.

  4. And click Next.

  1. Choose Blank App template, and click on Next.

  2. Click Create on the “Confirm & create” tab.

Here, you can customize your subdomain, but not necessarily to do, Altogic automatically creates one for you, your envUrl. You don’t need to worry if you lost your envUrl; you can get it from the Environments view of Designer.

Getting the environment URL

After creating our app, we need envUrl and clientKey to access our app via Altogic Client Library to create a web application.

To get the clientKey we need to enter the app which we have created before and;

  1. Click on App Settings at the left-bottom of the Designer.

  2. And click on the Client library keys section.

Getting the client key

We can create new clientKey from that page, but thanks to Altogic for creating one clientKey automatically for us, so let’s copy the existing clientKey from the list.

Create todo model

  1. Click on Models on the left sidebar.

  2. Click New on the right of the screen and select model.

  3. Set model name as todo

  4. Ensure that Enable timestamps are selected to store the creation date of the blog post.

  5. Click Next.

Altogic provides basic CRUD endpoints and services with the related model by default when you create a new model. Since we use Altogic Client Library, we won’t use these endpoints. Unselect all endpoints and click Create.

We created our first model, ”todo”. We have to define the model properties name, dateTime for the due date, and status. Since we created the todo model, we should define the name property as Text, dateTime as Date-time, and the status as Boolean.

  1. Click on the todo model on the Models page.

  2. Click on New Field on the right-top of the page.

  3. Select Text Field→ Text.

  4. Set model name name.

  5. Ensure that the Required field is selected.

  6. Click Create.

  1. Click on New Field on the right-top of the page.

  2. Select Boolean.

  3. Set model name status.

  4. Ensure that the Required field is selected.

  5. Set default value expression false.

  1. Click on New Field on the right-top of the page.

  2. Select Date-time.

  3. Set model name dateTime.

  4. Ensure that the Required field is selected.

  5. Set default value expression DATEADD(NOW(),5).

We completed the database design and the model definition on Altogic. Let’s move on to the front-end development.

Set up the front-end

Initialize a React app

We can use create-react-app​ command to initialize a React app:

npx create-react-app quickstart-todo

Then, install the Altogic package.

cd quickstart-todo
npm install altogic

Set up the environment variables

Environment variables are used to secure your secret keys, reuse them in different places and reduce production mistakes. Create a .env file in the root directory of your application, open the file in your editor and paste the following.

REACT_APP_ALTOGIC_ENV_URL=YOUR-APPLICATION-ENV-URL
REACT_APP_ALTOGIC_CLIENT_KEY=YOUR-APPLICATION-CLIENT-KEY

Replace YOUR-APPLICATION-ENV-URL and YOUR-APPLICATION-CLIENT-KEY with the envUrl and clientKey values you retrieved while setting up your backend.

Next, create a file to create the Altogic Client instance.

mkdir helpers
cd helpers
touch altogic.js

This creates an altogic.js file in the helpers directory. Open the file in your editor and paste the following.

import { createClient } from "altogic";

let envUrl = process.env.REACT_APP_ALTOGIC_ENV_URL;
let clientKey = process.env.REACT_APP_ALTOGIC_CLIENT_KEY;

const altogic = createClient(envUrl, clientKey);

export default altogic;

Here, you need to enter the envUrl and clientKey.

Now, install Tailwind CSS and create tailwind.config.js

cd ../
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Add the paths to all of your template files in your tailwind.config.js file.

module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};

Add the following directives to your index.css file.

@tailwind base;
@tailwind components;
@tailwind utilities;

Development

Since Altogic reduces the complexity of the backend development process, we will code our to-do app with just one main component: App.js

Feature & Function Matching:

  • Create a to-do → altogic.db.model("todo").create(todoInstance)

  • Update status of the to-do → altogic.db.model("todo").object(todoId).update({FIELD_NAME:newValue})

  • List all to-do’s → altogic.db.model("todo").get()

  • Delete a to-do → altogic.db.model("todo").object(todoId).delete()

We’ve covered all Altogic Client Library Functions that we used in our app. Let’s code it together!

import { useEffect, useState } from "react";
import altogic from "./helpers/altogic";

export default function Home() {
const [todos, setTodos] = useState([]);
/*
Inside your useEffect() hook, send a get request to Altogic using altogic.db.model(modelName).get() function of Altogic Client Library.
Then, set the data you fetched inside the todos state.
*/

useEffect(() => {
const fetchData = async () => {
const { data, errors } = await altogic.db.model("todo").limit(100).get();
if (data) {
setTodos(data);
} else {
console.log(errors);
}
};
fetchData();
}, []);

// Inputted todo name
const [todoName, setTodoName] = useState("");

/*
This function creates a todo instance on the database with the help of the Altogic Client Lİbrary db.model().create() function.
After creating an instance on the database, append the created object to the todos state
*/
const handleAddTodo = async (todoName) => {
try {
const { data, errors } = await altogic.db.model("todo").create({
name: todoName,
});
if (data) {
setTodoName("");
setTodos([...todos, data]);
} else {
console.log(errors);
}
} catch (error) {
console.log(error);
}
};

/*
We need to be able to update the status of our todos. We will implement a function called toggleTodo to send an update request to Altogic
for updating objects using altogic.db.model(modelName).object(objectId).update({}) function of Altogic Client Library.
Then, we will update the todo in the todos state by iterating the array.
*/
const toggleTodo = async (todo) => {
try {
const { data, errors } = await altogic.db
.model("todo")
.object(todo._id)
.update({
status: !todo.status,
});
if (data) {
setTodos(
todos.map((element) => {
if (element._id === todo._id) {
element = data;
}
return element;
})
);
} else {
console.log(errors);
}
} catch (error) {
console.log(error);
}
};

/*
We might also want to delete our todos. We will implement a function called handleDeleteTodo to send a delete request
to Altogic for deleting objects using altogic.db.model(modelName).object(objectId).delete() function of Altogic Client Library.
Then, we will delete the todo in the todos state by filtering the array.
*/
const handleDeleteTodo = async (todo) => {
try {
const { data, errors } = await altogic.db
.model("todo")
.object(todo._id)
.delete();
if (errors) {
console.log(errors);
} else {
setTodos(todos.filter((element) => element._id !== todo._id));
}
} catch (error) {
console.log(error);
}
};

return (
<div className="bg-slate-100 h-screen flex flex-col items-center justify-center">
<div>
<form>
<label>Add a new todo: </label>
<input
className="border-2"
type="text"
value={todoName}
onChange={(e) => setTodoName(e.target.value)}
></input>
<button
disabled={todoName === ""}
className="rounded bg-blue-600 ml-2 px-2 py-1 text-white"
onClick={(event) => {
event.preventDefault();
handleAddTodo(todoName);
}}
>
Submit
</button>
</form>
</div>
<div>
<ul>
{todos.map((todo) => {
return (
<li className="flex items-center mt-1" key={todo._id}>
<div className="flex items-center mr-2">
<input
type="checkbox"
checked={todo.status}
onChange={(event) => {
event.preventDefault();
toggleTodo(todo);
}}
></input>
<h2
className={`${
todo.status ? "line-through text-gray-400" : null
} ml-2 font-bold`}
>
{todo.name}
</h2>
</div>
<time
className={`${
todo.status ? "line-through text-gray-400" : null
} ml-2 font-bold`}
>
{todo.dateTime}
</time>
<button
className="rounded bg-red-600 ml-2 px-2 py-1 text-white"
onClick={() => handleDeleteTodo(todo)}
>
Delete
</button>
</li>
);
})}
</ul>
</div>
</div>
);
}

You can run your project by typing npm run start on the root directory of the project! You can check out the GitHub repository for the rest of the code.