Слайдове

Exam preparation: creating single-page app (CRUD + login / logout, with ReactJS) - JS Applications - ноември 2016

 

Материали от темата

Съдържание на документа

SPA with React and REST

Creating Single Page Apps (SPA)
with React, AJAX, REST and Kinvey

SoftUni Team

Technical Trainers

Software University

http://softuni.bg

AJAX

REST

Kinvey

SPA, AJAX
ReactJS,

Kinvey


Table of Contents

The Book Library App

The Kinvey Back-End

Creating React App

App Skeleton: React
Components + Views

Login / Register / Logout

Create List / Edit / Delete
Books (CRUD Operations)

2


3



sli.do
#spa-react

Have a Question?


The Book Library Project

Book Library: CRUD + Login / Logout


5

Design and implement a “Book Library” front-end single-page application (SPA) in HTML5 with REST back-end in Kinvey

Books have title, author and description

Implement the following functionality:

Login, register, logout, list all books, create a new book, edit existing book, delete existing book

Books have ownership:

Anyone can view all the books

Only the book creator can edit / delete his own books

The "Book Library" App


6

Home Screen






7

Login Screen






8

Login Screen: Invalid Login




9

Register Screen






10

List Books Screen




11

Create Book Screen






12

Edit Book Screen






13

Delete Book Screen








14

Logout Screen


The Kinvey-Based Back-End

Users and Books Collections


16

Create Kinvey App


17

Create a collection "books"











Add a few books

Columns: title + author + description

Create Books Collection


18

Test the Kinvey Back-End: Register User

POST

https://baas.kinvey.com/user/{app_id}/

Authorization: Basic base64(app_id:app_secret)

{"username":"todor", "password":"pass123"}


19

Test the Kinvey Back-End: Login User

POST

https://baas.kinvey.com/user/{app_id}/login

Authorization: Basic base64(app_id:app_secret)

{"username":"todor", "password":"pass123"}


20

Test the Kinvey Back-End: Logout

POST

https://baas.kinvey.com/user/{app_id}/_logout

Authorization: Kinvey authtoken


21

Test the Kinvey Back-End: List All Books

GET

https://baas.kinvey.com/appdata/{app_id}/books

Authorization: Kinvey authtoken


22

Test the Kinvey Back-End: Find Book by ID

GET

https://baas.kinvey.com/appdata/{app_id}/books/{id}

Authorization: Kinvey authtoken


23

Test the Kinvey Back-End: Create New Book

POST

https://baas.kinvey.com/appdata/{app_id}/books 

Authorization: Kinvey authtoken

{ "title":"ttt", "author":"aaa", "description":"ddd" }


24

Test the Kinvey Back-End: Edit Book

PUT

https://baas.kinvey.com/appdata/{app_id}/books/{id}

Authorization: Kinvey authtoken

{ "title":"t2", "author":"a2", "description":"d2" }


25

Test the Kinvey Back-End: Delete Book

DELETE

https://baas.kinvey.com/appdata/{app_id}/books/{id}

Authorization: Kinvey authtoken


Setup React Server-Side Build

Configuring the Development Environment


27

Install the React app creator (on-time global install):



Run the React app creator (this is very slow: ~5-10 minutes!)



Starts your React app from the command line



Browse you app from http://localhost:3000

Install and Run the React App Creator

npm -g install create-react-app

create-react-app React-Book-Library

npm start


28

React Apps with WebStorm


29

package.json – project configuration

Module name, dependencies, build actions

index.html

App main HTML file

index.js

App main JS file (startup script)

App.js, App.css, App.test.js

React component "App"

React App Structure


30

Run the React app from the console





Run the React app from WebStorm

Run the React App

npm start


Create the Application Skeleton

React App + Components + Views


32

Create the Project Structure


33

Start with the HTML Page: index.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="utf-8">

    <title>Book Library (React App)</title>

</head>

<body>

    <div id="app"></div>

</body>

</html>


34

Main App Script: index.js

import React from 'react';

import ReactDOM from 'react-dom';

import App from './App';

import './index.css';



ReactDOM.render(<App />,

  document.getElementById('app'));


35

Main App Styles: index.css

body {

  margin: 0;

  padding: 0;

  font-family: sans-serif;

}


36

Install jQuery from Node Package Manager

npm install --save jquery




37

Start from some imports

Main App Code: App.js

import React, { Component } from 'react';

import ReactDOM from 'react-dom';

import './App.css';



import NavigationBar from './Components/NavigationBar';

import Footer from './Components/Footer';



import $ from 'jquery';


38

Main App Code: App.js

export default class App extends Component {

  constructor(props) {

    super(props);

    this.state = {

      username: sessionStorage.getItem("username"),

      userId: sessionStorage.getItem("userId")

    };

  }

The app state will hold the currently logged in username + userId


39

Main App Code: App.js – render()

render() {

  return <div className="App">

    <header>

      <NavigationBar … />

      <div id="loadingBox">Loading ...</div>

      <div id="infoBox">Info</div>

      <div id="errorBox">Error</div>

    </header>

    <main id="main"></main>

    <Footer />

  </div>

}


40

Main App Code: Navigation Bar Component

<NavigationBar

  username={this.state.username}

  homeClicked={this.showHomeView.bind(this)}

  loginClicked={this.showLoginView.bind(this)}

  registerClicked={this.showRegisterView.bind(this)}

  booksClicked={this.showBooksView.bind(this)}

  createBookClicked={this.showCreateBookView.bind(this)}

  logoutClicked={this.logout.bind(this)} 

/>

Use bind(this) to fix the "lost this" problem


41

Main App Code: After Mount

componentDidMount() {

  // Attach global AJAX "loading" event handlers

  $(document).on({

    ajaxStart: function() { $("#loadingBox").show() },

    ajaxStop: function() { $("#loadingBox").hide() }

  });



  // Attach a global AJAX error handler

  $(document).ajaxError(

    this.handleAjaxError.bind(this));


42

handleAjaxError(event, response) {

  let errorMsg = JSON.stringify(response);

  if (response.readyState === 0)

    errorMsg = "Cannot connect due to network error.";

  if (response.responseJSON &&

      response.responseJSON.description)

    errorMsg = response.responseJSON.description;

  this.showError(errorMsg);

}

AJAX Error Handler


43

showInfo(message) {

  $('#infoBox').text(message).show();

  setTimeout(function() {

    $('#infoBox').fadeOut();

  }, 3000);

}



showError(errorMsg) {

  $('#errorBox').text("Error: " + errorMsg).show();

}

Info / Error Notification Boxes


44

showView(reactViewComponent) {

  ReactDOM.render(reactViewComponent,

    document.getElementById('main'));

  $('#errorBox').hide();

}

Show View in the Main App Area


45

showHomeView() {

  this.showView(<HomeView

    username={this.state.username} />);

}

Show Some Views

showLoginView() {

  this.showView(<LoginView

    onsubmit={this.login.bind(this)} />);

}

Bind the Home view with the App state to ensure updates when the state changes


46

import React, { Component } from 'react';

import './NavigationBar.css';

export default class NavigationBar extends Component {

  render() {

    let username = this.props.username;

    if (username == null) { // No user logged in

      return …;

    } else { // User logged in

      return …;

    }

  }

}

The Navigation Bar Component


47

// No user logged in

return (

  <nav className="navigation-bar">

    <a href="#" onClick={this.props.homeClicked}>

      Home</a>

    <a href="#" onClick={this.props.loginClicked}>

      Login</a>

    <a href="#" onClick={this.props.registerClicked}>

      Register</a>

  </nav>

);

Navigation Bar: No User Logged In


48

// User logged in

return (

  <nav className="navigation-bar">

    <a href="#" onClick={this.props.homeClicked}>Home</a>

    <a href="#" onClick={this.props.booksClicked}>

      List Books</a>

    <a href="#" onClick={this.props.createBookClicked}>

      Create Book</a>

    <a href="#" onClick={this.props.logoutClicked}>Logout</a>

    <span className="loggedInUser">Welcome, {username}!</span>

  </nav>

);

Navigation Bar: User Logged In


49

.navigation-bar {

    background: #DDD;

    text-align: center;

    padding: 10px 5px;

    line-height: 1.5;

    border-radius: 3px;

    overflow: auto;

}

.navigation-bar a {

    text-decoration: none;

    padding: 5px 10px;

    border-radius: 5px;

}

Navigation Bar CSS

.navigation-bar a:hover {

    background: #BBB;

}



.navigation-bar .loggedInUser {

    float: right;

    margin-right: 10px;

}


50

…

Footer.js


51

…

Footer.css


52

…

Home View


53

…

Login View


54

…

Register View


55

…

Books View


56

…

Create Book View


57

…

Edit Book View


58

…

Delete Book View


Login / Register / Logout

User Management with Kinvey


60

…

Kinvey Requester


61

…

Login


62

…

Register


63

…

Logout


64

Test the User Registration: Success


65

Test the User Registration: Error


Implementing CRUD Operations

List / Create / Delete / Edit


67

…

View Books


68

…

Create Book


69

…




70

…




71

…




72

…




73

…




74

…




75

Test: List Books


76

…




77

…




78

Test: Create New Book


79

…




80

…




81

Test: Display Edit / Delete Links


82

…




83

…




84

Test: Delete Book


85

…




86

…




87

Test: Edit Book




Practice: "Book Library" React App

Live Exercises in Class (Lab)


89

…

Summary


https://softuni.bg/courses/javascript-applications

SPA with React and REST


License

This course (slides, examples, demos, videos, homework, etc.)
is licensed under the "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International" license

91


Free Trainings @ Software University

Software University Foundation – softuni.org

Software University – High-Quality Education, Profession and Job for Software Developers

softuni.bg 

	Software University @ Facebook

	facebook.com/SoftwareUniversity

	Software University @ YouTube

	youtube.com/SoftwareUniversity

	Software University Forums – forum.softuni.bg