lunes, 9 de agosto de 2021

React Elemental Course

React Elemental Course 

Add, Edit, Remove comments list
 
  
Before click edit button in first comment. 


After click edit button in first comment

Comment edited and clicked on save button

Before click remove button in second comment

After click remove button in second comment

Deleted all comments before click on Add New Comment Button

Clicked five times to add five new comments

 
 
  1. Initial Start, Install and Config, prepare simple html
  2. Simple Demo
  3. Components
  4. Rendering Multiple Components
  5. Props
  6. Event Handling
  7. this.props.children
  8. State
  9. Adding State to Components
  10. Refs
  11. Multiple Child Components
  12. Updating State and Removing Components
  13. Passing Functions as Props
  14. Creating New Components


Continue from

https://www.youtube.com/watch?v=szmS_M-BMls&list=PL6gx4Cwl9DGBuKtLgPR_zWYnrwv-JllpA&index=13&ab_channel=thenewboston

1. Initial Start, Install and Config, prepare simple html

 Install nodejs, react, visual code studio

Create React App 

install node.js
install visual studio code

google create react app, find github.com/facebook/create-react-app where the instrucctions are.

for short
>npx create-react-app react-frontend
>cd react-tutorials
>npm start

Our project is in react-tutorials directory

then it runs on https://localhost:3000/

to sligly modify it, on App.js file modify adding something like
   <h1> My react App is working!</h1>

just to test it.

Now, The React App is working, but we will delete some files to make it simpler for the course, to start with a simple index.html to understand. basically delete logo, icons, reportWebVitals, and simplify App.js and index.js files.

2. Simple Demo


blabla

3. Components


blabla

4. Rendering Multiple Components


blabla

5. Props

 
The set value of the props is for the rest of the life cicle of the component.

blabla

6. Event Handling

 
blabla
 

7. this.props.children


blabla

8. State


When we need to change the value of a prop of the component, we may use the state, this allows change the value refering as state of the component.

9. Adding State To Components

  Identify two states of the form, one as normal and other when editing. so we need to add state to this componen and manage accord each state, so when the edit button is clicked the editing state is active, redrawing a edit form with a save button, and when the save button is clicked then the state editing is off. showing the normal form.

In the edit form (renderForm) we manage the input type="text" to load the previous value using defaulvalue="this.props.children", and autoFocus with the text selected by calling this.handleFocus.

handleFocus = (event=> event.target.select();
... 
<input type="text" className="alert alert-light col" autoFocus 
              onFocus={this.handleFocus} defaultValue={this.props.children}></input>
              

 col in className in the bootstrap class to fix correctly the input along the container.



10. Refs

To take the value from the component, we can not use id, we need to use ref from the component, in this case we name the ref as newText.

11. Multiple Child Components

Lets create another component Board which has in his state an array of comments, this array cound be changed in their elements of comments. to display. we use the map function of the array which process for each element of the array the process in the anonymous function.

12. Updating State and Removing Components

In the Board component refactor the map extracting the function and adding index={i} to allow us take the index, and create two functions removeComment and updateComments which alter the state comments in order to remove or update the respective comment.

13. Passing Functions as Props

From the Comment component we need to call the methods removeComment and updateComment of Board Component, so we need to declare a prop in Board Component with his functions removeComment and updateComments in order that Comment component just has to access to it by this.props.nameFunction. So this way the child has access to the parent methods simply accessing it by the props that are mapped to these methods.

14. Creating New Components

bla bla

Finished code in only one file, need to be refactorized separating the components and script on diferent files.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>

    <!-- Cargar React. -->
    <!-- Nota: cuando se despliegue, reemplazar "development.js" con "production.min.js". -->
    <script
      src="https://unpkg.com/react@17/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <!-- Latest compiled and minified CSS -->
    </script>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
      integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div id="container"></div>

    <script type="text/babel">
      class Comment extends React.Component {
        constructor(props){
          super(props);
          this.state = { editing: false}
          console.log("constructor"this.state.editing);
        }

        handleFocus = (event=> event.target.select();

        onKeyUp = (event=> { 
          var val = event.target.value;
          if (event.charCode === 13) {
            //this.setState({ inputValue: val});
            this.props.updateCommentText(this.refs.newText.valuethis.props.index);
            this.setState( { editing: false});
            console.log("onKeyUp :" + val);
          }  
        };

        edit = () => {
           this.setState( { editing: true})
        };

        remove = () => { 
          console.log("remove comment");
          this.props.removeFromBoard(this.props.index)
        };

        save = () => { 
          this.props.updateCommentText(this.refs.newText.valuethis.props.index);
          this.setState( { editing: false})
        };

        renderNormal() {
          return (
            <div className="container alert alert-primary">
              <div className="alert alert-light">{this.props.children}</div>
              <button onClick={this.edit} className="btn btn-primary">edit</button>
              <button onClick={this.remove} className="btn btn-danger" style={{marginLeft: "10px"}}>remove</button>
            </div>
          );}

        renderForm() {
          return (
            <div className="container alert alert-primary">
              <div>
              <input type="text" className="alert alert-light col" ref="newText" 
              autoFocus onFocus={this.handleFocus} defaultValue={this.props.children}
              onKeyPress={this.onKeyUp}></input>
              </div>
              <button onClick={this.save} className="btn btn-success">save</button>
            </div>
          );
        }

        render() {
          console.log("render editing: "this.state.editing);
          if(this.state.editing)return this.renderForm(); 
          else        
            return this.renderNormal();
        };
      }

      class Board extends React.Component {
        constructor(props){
          super(props);
          this.state = { comments : ["How to refer to this comment by component",
            "you need to use this.props.children",
            "refer this comment element by the component"],
          };
          this.removeComment = this.removeComment.bind(this);
          this.updateComment = this.updateComment.bind(this);
          this.addComment = this.addComment.bind(this);
        }

        removeComment(i){
          console.log("removing comment: " + i);
          var arr = this.state.comments;
          arr.splice(i1);
          this.setState({ comments: arr})
        }

        updateComment(newTexti) {
          console.log("updating comment: " + i);
          var arr = this.state.comments;
          arr[i] = newText;
          this.setState({ comments: arr})
        }

        addComment(text){
          console.log("addComment: " + " " + text);
           var arr = this.state.comments;
           arr.push(text);
           this.setState({ comments: arr});
        }

        render() {
          return (
            <div className="board">
            <button className="btn btn-info btn-block create" 
              onClick={ this.addComment.bind(this"New comment here!"}>Add New Comment</button><br/>
            {
              this.state.comments.map( (texti=> {
                return (<Comment key={i} index={i} updateCommentText={this.updateComment}
                 removeFromBoard={this.removeComment}>
                 {text} 
                 </Comment>)
              })
            }
            </div>
          )  
        }
   };

      ReactDOM.render(
        <Board />,
        document.querySelector("#container")
      );
    </script>
  </body>
</html>


 

 

 

 

eot

jueves, 5 de agosto de 2021

React - Spring Boot Full Stack FrontEnd BackEnd Person Entity CRUD App

React - Spring Boot Full Stack FrontEnd BackEnd Person Entity CRUD App

Simple CRUD application






List Persons


Add Person


List Person after Add Person


List Persons after Delete Person


Update Person


List Person after Update person


Detail Person



CRUD features

- Create Person
- List Person
- Update Person
- Delete Person
- View Person

React is used to build user interfaces on the fron end.
Spring boot to develop REST web services and microservices. reduces configuration and set up time required for 
spring projects.

REST api call from React to Spring Boot RESTfull API
basic React components JSX, State and Props

Tools and Technologies


- React
- Modern JaveScript (ES6)
- NodeJs and NPM
- VS Code IDE
- Create React App CLI
- Bootstrap 4.5 and Axios HTTP Library
- Spring Boot 2+
- SprinData JPA (Hibernate)
- Maven 3.2+
- JDK 1.8
- Embedded Tomcat 8.5+
- PostgreSQL database


Create Spring Boot Project

New Spring starter Project
springboot-backend
Maven jar
8 java

Spring boot version 2.3.1
Spring Boot DevTools
Spring Data JPA
MySQL Driver
Spring Web

Create DataBase Person   (Postgress)  
pgAdmin4
1ht   password: betopass
2nd   password: password

Database personMS, table person

Config dataSource
  application.properties
  spring.datasource.url=...

Create Packages
- controller
- exception
- model
- repository

On model
  person
id
firstName
lastName
email

Add anotations @Entity, @Table, @Id, @GeneratedValue, @Column

On repository package
   @Repository
   interface PersonRepository extends JpaRepository<Table,ID>

On Exception package
    @ResponseStatus(value= HttpStatus.NOT_FOUND)
    ResourceNotFoundException extends RuntimeException 

Add PersonController on Controller package
    Add @RestController
@RequestMapping("/api/v1/")

    inject PersonRepository with @Autowired
    
    add method List<Person> getAllPersons() , @GetMapping("/persons")

Test with browser with localhost:8080/api/v1/pesons
 or with postman 

Create React App 

install node.js
install visual studio code

google create react app, find github.com/facebook/create-react-app where the instrucctions are.

for short
>npx create-react-app react-frontend
>cd react-frontend
>npm start

then it runs on https://localhost:3000/

to sligly modify it, on App.js file modify adding something like
   <h1> My react App is working!</h1>

just to test it.

The React project has a package.json file with 
  - dependencies
  - scripts

The README.me file has the basic instruccions for run and test the app.

On the file node_modules are the dependency packages included and installed for our app.
On public directory we have index.html, in it we have de div root where dinamically react construct all the componenst

On App.js we are going to add jsx files code recomended by react to build components
On index.js we invoke App component which will be rendered.

Add BootStrap 4 in React App

On Visual Code Studio

add bootstrap lib to project
Method 1 by link in html file
- go to google search bootstrap 4 cdn, in page look for link to integrate in index.html, in this case

index.html, this has to be added independently to do the method of npm install bootstrap, at least for the test work for me
...
work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
...   

Method 2 by installing with npm
- in second integrated terminal (powershell)
npm install bootstrap --save         save for integrate in package.json

now we can see it on package.json dependencies

on index.js import 'bootstrap/dist/css/bootstrap.min.css';

Create React List Person Component

initialize git for tracking

-- Creating a listPerson Component in React

Add src/components/ListPersonComponent.jsx

we will use react snippets , googlear react snippets for vs code  -> reactjs code snippets

create the component Person and add it to app.js
type rcc and is sugested create a React class component

The on the method render return on div, we create the code to form the html div, in this case the Person List with classNames styles and fields with data.
  The state has the persons array where the data of persons will be extracted, using map to process each element of the array to be displayed in the table.

Connecting React with List Person RESTAPI

We can use Axios http library, or browser fetch api tool, in this case we'll use axios library to make the http call

npm install axios --save

  Create src/services/PersonService.js with class PersonService and function getPersons
using axios to get the url http://localhost:8080/api/v1/persons

And export the class PersonService to be able to be usen on the component

Then in ListPersonComponent.jsx add method componentDidMount() which is called when the method immediate it is mounted, 
setting the state here and trigger re-rendering.
  This will call service person to get persons as a promise. setting the state with persons array with data from the call to axios backend.

Se hacen ajustes en el controller de Spring boot add @CrossOrigin(origins = "http://localhost:3000")

Creating React Header and Footer Components

Create components HeaderComponent.jsx and FooterComponent.jsx

Configure Routing

we´ll use react routing for this lab, install npm install react-router-dom
import BrowserRouter as Router, Route, and Switch on App.js
Add Router, Switch and Route on div in app.js, just to be displayed the ListPersonComponent in order to the route
  /, /persons, default

Create Add Person REST API

@PostMapping("/persons")
public Person createPerson(@RequestBody Person person) {
   return personRepository.save(person);

Test on Postman with Content-Type application/json, body with json object with person data, check the response

Creating React Add Person Component

Create components/CreatePersonComponent.jsx
create the route to switch to the CreatePersonComponent, this on App.js.

Add button and functionality add person in ListPersonComponent.jsx to push in the router history the desired route.
and bind the object onclick button in the constructor to call addPerson(), use of exact in route

addPerson(){
  this.props.history.push('/add-person');
}

adjust an issue in route / by adding exact to the route. so AddPerson Component can be called.

React Add Person From Handling

On CreatePersonComponent construct the html elements of the form with their respective css bootstrap in order to form
the desired form structure.

  <div className="container">
    ...
       <form>
         ...
         <label>First Name</label>
<input className="form-control" name="firstName" placeholder="First Name"
                value={this.state.firstName} onchange={this.changeFirstNameHandler}/>
         ...
        </form>
     ...
  </div>  

- in constructor initialize state with clean values to elements data of the form, firstName, lastName, email
- construct the elements for html of the from for the elements of data of the form, values taken from state, and onChange
call a function to set the captured values to the state. Bind each function to the class component CreatePersonComponent
in the constructor of the class with .bind(this). The function savePerson create an object person and initialize it with the 
state

Connect React with Add Person REST API

in React service/PersonService.js add method createPerson(Person) and call axios.post(URL, person), and call it 
in CreatePersonComponent.savePerson()


Create Get Person by Id REST API

add controller the mapping with parameter @GetMapping("/persons/{id}")
  ... getPersonById(@PathVariable Long id)
  Person person = personRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("messageX" + id);
  return ResponseEntity.ok(person);

Test on postman 

Create Update Person REST API

   get the person, if exist then asign the new data values and save de person

Create React update Person Component

- On ListPersonComponent.jsx button update will call updatePerson(person.id). which calls the route /update-person/${id}
  this.props.history.push(`/update-person/${id}`

- Add the route with parameter id in App.js
  <Route path="/update-person/:id" component={UpdatePersonComponent}

- Clone de CreatePersonComponent and corresponient parts to UpdatePersonComponent, the Components´s name and the function called by
  the button, This component need to take the id from the list of persons from it where called, this is initialized  in the constructor 
  and the id: this.props.match.params.id.
  On componentDidMount it calls PersonServie.getPersonById to get the person Id Data and assign to the state

  2:19 test the functionality
  In browser check the update form and the console.log to see the person variable updated.

Connecting React with Update Person REST API

- PersonService.updatePerson( person, personid) { return axios.put(PERSON_API_BASE_URL + "/" + personId, person);
- add in UpdatePersonComponent.updatePerson call to PersonService.updatePerson( person, this.state.id).then((res) => {
  this.props.history.push("/persons");
  }

Add & Update Person with Single React Component.

(Reusing CreatePersonComponent for UpdatePersonComponent)

- use the route of add-person this id param, if id negative it is an add if is posititve it is an update.
  or use something === '_add' in url call and do the logic.

-step 1
eliminate de update route on App.js
modify the route of add-person to accept id as parameter "add-person/:id"

-step 2
In CreatePersonComponent.jsx in this.state add id: this.props.match.params.id;
-step 3
in CreatePersonComponent.jsx add componentDidMount(), with PersonService.getPersonById(this.state.id) and set the response
data of Person to the state.
-step 4
Add a conditional in componentDidMount to return if id is negative else do what the step 3 do.
-step 5
In CreatePersonComponent.jsx in savePerson add the condition that when -1 do createPerson else do updatePerson

Creating Delete Person REST API

deleted by id
return map<String, Boolean>
with deleted, true

test with postman

Connecting React with Delete Person API

add PersonService.deletePersonById(id) and on the promise response setState of person with filter the array with the persons
not deleted.

Create React View Person Component

Create a button to see the details of the person because these data are to many for the table.

Create ViewPersonComponent.jsx
Add it to the App.js with route "/view-person/:id"
add button to ListPersonComponent and on click call viewPerson, viewPerson method will push the URL
/view-person/${id}

Design and Show Data on View Person Page

On the state of the viewPersonComponent we initialize the state of the id from the route with
this.state = {
  id: this.props.match.params.id,
  ...

To get the rest of the Person Data we will do a REST API call by id on componentDidMount()



Notes:
POST Create
GET Read
PUT Update/Replace
PATCH Update/Modify
DELETE  Delete

Links:

https://github.com/jalbertomr/springboot-backend

References:

Java Guides, Remesh Fadatare


eot

viernes, 4 de junio de 2021

SpringIoC From Tight to Loose Coupling, Debug, Error Messages

From Tight to Loose Coupling with Spring IoC (Inversion of Control)

https://github.com/jalbertomr/SpringIoC.git 

Highly Coupled Classes


To Run other Class is needed modify Classes


Decoupling a little using Interface

To change the game just change the new Class for GamingConsole game variable.




Decoupling using sprinc IoC
Creating Context from Spring to use the beans.   (Ctrl+1 to create new local variable).


Is proposed the names, between them context.


There in no needed to use new to instantiate any class, Spring IoC do the job for you.


Add @Component  and @Primary

Specifying where packages to find the beans.




To Debug spring framework






Forcing  Spring to not find the bean to show the respective error message.


Dependency Injection using Constructor


Dependency Injection using Setter.

Dependency Injection using Field


eot