Wednesday, March 6, 2019

React using state and props, Shopping Cart MVC 2019

React using state and props, Shopping Cart MVC 2019

I mean, the simplest example learning how to use the React state, and React props

( Clearly here i'm not using Redux, this is the next step, just to be clear )

React state of the App

React props of each React.Component Instance

So we can have list of products, and a shopping cart (list of items of products), adding and removing items.

The point is to learn how to pass action control over components, changing from state to new states on action events from components, to the Root App, and showing the change in the other affected Component.

https://codesandbox.io/s/v0l1knv1yl

https://github.com/maximilianou/react_2019_state_props_shoppingcart_mvc/

https://gitlab.com/maximilianou/react_2019_state_props_shoppingcart_mvc

https://bitbucket.org/maximilianou/react_2019_state_props_shoppingcart_mvc


import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const ProductsList = props => {
  const { products, adding } = props;
  return (
    < section>
      < h2>List of Products< /h2>
      {products.map(product => (
        < article key={"product_" + product.id}>
          < h4>{product.name}< /h4>
          < span>{product.price}< /span>
          < button onClick={adding} value={JSON.stringify(product)}>
            +
          < /button>
        < /article>
      ))}
    < /section>
  );
};
const ItemsList = props => {
  const { items, removing } = props;
  return (
    < section>
      {items.map(item => (
        < article key={"item_" + item.product.id}>
          < h4>{item.product.name}< /h4>
          < span>{item.product.price}< /span>
          < span>{item.quantity}< /span>
          < span>{item.quantity * item.product.price}< /span>
          < button onClick={removing} value={JSON.stringify(item)}>
            -
          < /button>
        < /article>
      ))}
    < /section>
  );
};
class ShoppingCart extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      < section>
        < h2>Shopping Cart< /h2>
        < ItemsList items={this.props.items} removing={this.props.removing} />
      < /section>
    );
  }
}
class App extends React.Component {
  state = {
    products: [
      { id: 20, name: "Limonade", price: 200 },
      { id: 21, name: "Green Tea", price: 150 },
      { id: 22, name: "Chocolate Milk", price: 350 }
    ],
    items: []
  };
  constructor(props) {
    super(props);
    this.adding = this.adding.bind(this);
    this.removing = this.removing.bind(this);
  }
  adding = evt => {
    const product = JSON.parse(evt.target.value);
    let item = this.state.items.find(ite => ite.product.id === product.id);
    if (item === null || item === undefined) {
      item = {};
      item.product = product;
    }
    if (item.quantity === undefined) {
      item.quantity = 1;
      this.setState({ items: [...this.state.items, item] });
    } else {
      item.quantity += 1; // mm.. here i'm changing the original object. mmm...
      this.setState({ items: [...this.state.items] });
    }
  };
  removing = evt => {
    const item_p = JSON.parse(evt.target.value);
    const item = this.state.items.find(
      ite => ite.product.id === item_p.product.id
    );
    if (item.quantity === 1) {
      const listItems = this.state.items.filter(
        ite => ite.product.id !== item.product.id
      );
      this.setState({
        items: listItems
      });
    } else {
      item.quantity -= 1; // mmm.. here i'm changing the original object. mmm...
      this.setState({ items: [...this.state.items] });
    }
  };
  render() {
    return (
      < div className="App">
        < ProductsList products={this.state.products} adding={this.adding} />
        < ShoppingCart items={this.state.items} removing={this.removing} />
      < /div>
    );
  }
}

const rootElement = document.querySelector("#root");
ReactDOM.render(<  App />, rootElement);

Friday, February 1, 2019

running test sample puppeteer docker compose debian 9

Here we have a simple sample, to run puppeteer and check OK or NOT browsing uno site.

educacion@family:~/src$ hg clone https://bitbucket.org/maximilianou/docker17_puppeteer


educacion@family:~/src/docker17_puppeteer/frontest$ docker-compose up


educacion@family:~/src/docker17_puppeteer/frontest/test$ cat index.spec.js 
const assert    = require('assert');
const puppeteer = require('puppeteer');
describe("Browsing with puppeteer:", ()=> {
  describe("Geting one page", ()=>{
    it("Check OK:",  async ()=> {
        const browser = await puppeteer.launch({
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox'
            ]
        });    
        const page = await browser.newPage();
        await page.goto('https://bitbucket.org/maximilianou/'); //, {waitUntil: 'networkidle2'});    
        let textResponse = await page.evaluate(() => {
          //Maximiliano Usich
          let elemCheck = document.querySelector('a[href="/maximilianou/"]');
          return elemCheck.innerHTML;
        });
        assert( textResponse === 'Maximiliano Usich', "[OK] Content Found" );
        browser.close();
    });
    it("Check Not Found:", async ()=> {
        const browser = await puppeteer.launch({
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox'
            ]
        });    
        const page = await browser.newPage();
        await page.goto('https://bitbucket.org/maximilianou/UPS!!');// , {waitUntil: 'networkidle2'});    
        let textResponse = await page.evaluate(() => {
          //Maximiliano Usich
          let elemCheck = document.querySelector('a[href="/maximilianou/"]');
          return elemCheck;
        });
        assert( textResponse === null, "[OK] Content Not Found" );
        browser.close();
        
      });
  });
});



educacion@family:~/src/docker17_puppeteer/frontest$ cat Dockerfile 
FROM alekzonder/puppeteer
# set working directory
#RUN mkdir /app
WORKDIR /app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/package.json
COPY test /app/test
RUN npm install
# start app
CMD ["npm", "run", "test"]


educacion@family:~/src/docker17_puppeteer/frontest$ cat docker-compose.yml 
version: '3.5'
services:
  docker-test-puppeteer:
    container_name: docker-test-puppeteer
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - '.:/app'
      - '/app/node_modules'
    ports:
      - '3333:3333'
    environment:
      - NODE_ENV=development

ERROR: when an error like this happen

docker-test-puppeteer    |   1) Browsing with puppeteer:
docker-test-puppeteer    |        Geting one page
docker-test-puppeteer    |          Check OK::
docker-test-puppeteer    |      Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/app/test/index.spec.js)

The site did NOT responde on time ( 10000 milis). We have configured this in package.json

educacion@family:~/src/docker17_puppeteer/frontest$ cat package.json 
{
  "name": "frontest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "node_modules/mocha/bin/mocha --timeout 10000  test/index.spec.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mocha": "^5.2.0"
  }
}

This is the way of code, set the timeout in the it().timeout(0), because mocha take 2 seconds.

const assert    = require('assert');
const puppeteer = require('puppeteer');
describe("Browsing with puppeteer:", ()=> {
  describe("Geting one page", ()=>{
    it("Check OK:",  async ()=> {
        const browser = await puppeteer.launch({
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox'
            ]
        });    
        const page = await browser.newPage();
        await page.goto('https://bitbucket.org/maximilianou/', {waitUntil: 'domcontentloaded'}); //, {waitUntil: 'networkidle2'});    
        let textResponse = await page.evaluate(() => {
          //Maximiliano Usich
          let elemCheck = document.querySelector('a[href="/maximilianou/"]');
          return elemCheck.innerHTML;
        });
        assert( textResponse === 'Maximiliano Usich', "[OK] Content Found" );
        browser.close();
    }).timeout(0);;
    it("Check Not Found:", async ()=> {
        const browser = await puppeteer.launch({
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox'
            ]
        });    
        const page = await browser.newPage();
        await page.goto('https://bitbucket.org/maximilianou/UPS!!', {waitUntil: 'domcontentloaded'});// , {waitUntil: 'networkidle2'});    
        let textResponse = await page.evaluate(() => {
          //Maximiliano Usich
          let elemCheck = document.querySelector('a[href="/maximilianou/"]');
          return elemCheck;
        });
        assert( textResponse === null, "[OK] Content Not Found" );
        browser.close();
        
      }).timeout(0);;
  });
});

install docker compose in debian 9

Installing docker-compose in debian 9

root@family:/home/educacion/src/docker17_puppeteer/frontest# curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose


root@family:/home/educacion/src/docker17_puppeteer/frontest# chmod +x /usr/local/bin/docker-compose


root@family:/home/educacion/src/docker17_puppeteer/frontest# docker-compose --version
docker-compose version 1.23.2, build 1110ad01



install docker in debian 9

Installing docker in debian 9

root@family:/home/educacion/src/docker17_puppeteer/frontest# apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common


root@family:/home/educacion/src/docker17_puppeteer/frontest# curl -fsSL https://download.docker.com/linux/debian/gpg |  apt-key add -


root@family:/home/educacion/src/docker17_puppeteer/frontest# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"


root@family:/home/educacion/src/docker17_puppeteer/frontest# apt update


root@family:/home/educacion/src/docker17_puppeteer/frontest# apt-cache policy docker-ce
docker-ce:
  Installed: (none)
  Candidate: 5:18.09.1~3-0~debian-stretch
  Version table:
     5:18.09.1~3-0~debian-stretch 500
        500 https://download.docker.com/linux/debian stretch/stable amd64 Packages


root@family:/home/educacion/src/docker17_puppeteer/frontest# apt install docker-ce


root@family:/home/educacion/src/docker17_puppeteer/frontest# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-02-01 17:04:43 -03; 50s ago
     Docs: https://docs.docker.com


root@family:/home/educacion/src/docker17_puppeteer/frontest# usermod -aG docker educacion


educacion@family:~/src/docker17_puppeteer$ docker run node


REFERENCE: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-debian-9

install node modules globally in debian 9

Installing node modules globally in debian 9 The unix way, your user need to be part of staff group

educacion@family:~/src/docker17_puppeteer$ fgrep educacion /etc/group
staff:x:50:educacion
ssh:x:113:educacion
educacion:x:1000:

Now you have clean access to /usr/local, because you are part of staff group, it's the unix way ( try to not use sudo, not been part of sudo )

educacion@family:~/src/docker17_puppeteer$ npm set prefix /usr/local

educacion@family:~/src/docker17_puppeteer$ npm install -g jshint
/usr/local/bin/jshint -> /usr/local/lib/node_modules/jshint/bin/jshint
+ jshint@2.9.7

install vs code debian

Install visual code in debian


root@family:/home/educacion/src/docker17_puppeteer# apt install software-properties-common apt-transport-https

root@family:/home/educacion/src/docker17_puppeteer# wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | apt-key add -


root@family:/home/educacion/src/docker17_puppeteer# add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"


root@family:/home/educacion/src/docker17_puppeteer# apt update


root@family:/home/educacion/src/docker17_puppeteer# apt install code

install nodejs in debian

Installing nodejs in debian 9


root@family:/home/educacion/src/docker17_puppeteer# curl -sL https://deb.nodesource.com/setup_11.x -o nodesource_setup.sh


root@family:/home/educacion/src/docker17_puppeteer# chmod +x nodesource_setup.sh 

root@family:/home/educacion/src/docker17_puppeteer# ./nodesource_setup.sh 

root@family:/home/educacion/src/docker17_puppeteer# apt install -y nodejs

root@family:/home/educacion/src/docker17_puppeteer# node --version
v11.9.0

Monday, January 21, 2019

react redux one source file sample all components january 2019

Trying to simplify One File Source Code Explanation of React Redux.

This is the minimal example i have seen.

>React Redux, 'there is nothing new under the sun', i had an interview, i didn't know react redux at the time, i clearly sed that. So i Solved an exercise without react redux. I just write down vanilla javascript ES6, class, view, model, controller, html css. So, when the interview finished, i started searching, reading blogs, three days later.. here you have, react redux, it's not so complex. So Developers, 'there is nothing new under the sun', if you manage design patterns have a day with this, and there is it running. )

https://github.com/maximilianou/docker15_react_redux_onefile https://www.linkedin.com/pulse/developer-you-only-need-three-days-learn-react-redux-usich/?published=t
( This could help in a realtime interview, clone, cut and paste, npm install, and do the react redux exercise, 

showing that you manage the concepts, fast, clear.. or not so.

Changing this code, 

Adding inputs in the form, or adding another form (jsx, React.Component), "connecting it with the redux store" 

Changing the view, or adding another views (jsx, React.Component) "connecting it with the redux store", 

Making more actions, will help you show faster your understanding of react redux.

Show how to make many differents redux stores, 
for a partition of your busness data layer in this presentation layer.

- Later you talk about Hierarchy of the filesystem, were you will write down your .js files ('like unix man hier') when you have many business logic accions. 

/actions/

/constants/

/reducers/

/components/

)

---

I run the environment with, editor vscode, docker-compose just to use it.
And we can change the code, and see changes on runtime.
code . 

docker-compose up

```javascript

// index.js, react redux, onefile flatting explanation.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import { Provider, connect } from "react-redux";
import './App.css';
import uuidv1 from "uuid";
import { createStore } from 'redux'; 
//// Route (business logic) actions, with tipified constant Names.
//// To change de state of the Global store App
const ADD_ARTICLE = "ADD_ARTICLE";
const initialState = {
  articles: []
};
const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_ARTICLE:
      return { ...state, articles: [ ...state.articles, action.payload ] };    
    default:
      return state;
  }
};
//// Create an "Input Form React Component", connected with redux store state.
//// Write down the html view of this component.
//// Write down the handlers in javascript methods, for dom events. 
//// Connect the dom events handlers in the html view.
//// Dispatch de state of the Component, to the redux (global) store.
const store = createStore(rootReducer);
const addArticle = article => ({
  type: ADD_ARTICLE,
  payload: article
});
const mapDispatchToProps = dispatch => {
  return {
    addArticle: article => dispatch(addArticle(article))
  };
};
class ConnectedForm extends React.Component {
  constructor() {
    super();
    this.state = {
      title: ""
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(event) {
    this.setState({ [event.target.id]: event.target.value });
  }
  handleSubmit(event) {
    event.preventDefault();
    const { title } = this.state;
    const id = uuidv1();
    this.props.addArticle({ title, id });
    this.setState({ title: "" });
  }
  render() {
    const { title } = this.state;
    return (
      < form onSubmit={this.handleSubmit} >
        < div className="" >
          < label htmlFor="title">Title< /label >
          < input
            type="text"
            className=""
            id="title"
            value={title}
            onChange={this.handleChange}
          / >
        < /div >
        < button type="submit" className="" >
          SAVE
        < /button >
      < /form >
    );
  }
}
const Form = connect(null, mapDispatchToProps)(ConnectedForm);
//// Create a Function with de html view in jsx from react, 
//// And connect the state properties to the redux store
//// Like an observer/observable, from general design patterns.
const mapStateToProps = state => {
  return { articles: state.articles };
};
const ConnectedList = ({ articles }) => (
  < ul className="" >
    {articles.map(el => (
      < li className="" key={el.id} >
        {el.title}
      < /li >
    ))}
  < /ul >
);
const List = connect(mapStateToProps)(ConnectedList);
//// Create de view in jsx, width html and React Component of the Application
const App = () => (
  < div className="App" >
    < div className="App-header" >
      < h2 >Add a new article< /h2 >
      < Form / >
    < /div >
    < div className="" >
      < h2 >Articles< /h2 >
      < List / >
    < /div >
  < /div >
);
//// Making the action of rendering the final DOM in html, in 'index.html'->'div#app'
//// we have to connect the Global Redux store of the Rreact App, 
////       with the Provider react-redux Component
ReactDOM.render(
  < Provider store={store} >
    < App / >
  < /Provider >,
  document.querySelector("#app")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

```

https://bitbucket.org/maximilianou/docker15_react_redux_onefile/

https://github.com/maximilianou/docker15_react_redux_onefile

REFERENCE: https://dev.to/valentinogagliardi/react-redux-tutorial-for-beginners-learning-redux-in-2018-13hj

Thursday, January 17, 2019

javascript react docker initial development environment

REFERENCE: https://mherman.org/blog/dockerizing-a-react-app/

1. This recipe really run well, so. Installing scaffolding tools from react script over npm.

educacion@educacion:~/src/docker13react$ npm install create-react-app

2. Creating a default app, ( scaffolding ) frontend in this case.

educacion@educacion:~/src/docker13react$ npx create-react-app frontend

3. Looking what files were created.

educacion@educacion:~/src/docker13react$ cd frontend/
educacion@educacion:~/src/docker13react/frontend$ ls
Dockerfile  node_modules  package.json  public  README.md  src  yarn.lock

4. Create the docker file, from the tutorial reference.

educacion@educacion:~/src/docker13react/frontend$ cat Dockerfile 
# base image
FROM node
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install --silent
RUN npm install react-scripts@1.1.1 -g --silent
# start app
CMD ["npm", "start"]

5. There are some files that can be excluded from de docker image.

educacion@educacion:~/src/docker13react/frontend$ cat .dockerignore 
node_modules

6. Building the docker image for initial react development.

educacion@educacion:~/src/docker13react/frontend$ docker build -t react-docker .

7. Running the docker image in port 3000, exported and binded with the localhost port.

educacion@educacion:~/src/docker13react/frontend$ docker run -it -v ${PWD}:/usr/src/app -v /usr/src/app/node_modules -p 3000:3000 --rm react-docker

http://localhost:3000/ 

8. Using docker compose.

educacion@educacion:~/src/docker13react_initial/frontend$ cat docker-compose.yml 
version: '3.5'
services:
  react-docker:
    container_name: react-docker 
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - '.:/usr/src/app'
      - '/usr/src/app/node_modules'
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development

9. Running docker compose

educacion@educacion:~/src/docker13react/frontend$ docker-compose up

10. Ckecking if it is running (manually).

http://localhost:3000/ 

11. Running the visual code editor, for runtime development.

educacion@educacion:~/src/docker13react$ ls
frontend  node_modules  package.json  package-lock.json

educacion@educacion:~/src/docker13react$ code .

12. And now!, It's running OK, pushing to the repository, on bitbucket.org with mercurial.

educacion@educacion:~/src$ hg clone https://bitbucket.org/maximilianou/docker13react_initial

educacion@educacion:~/src/docker13react_initial$ cp -R ../docker13react/* .

13. Adding new files to the repository

educacion@educacion:~/src/docker13react_initial$ hg add .

educacion@educacion:~/src/docker13react_initial$ hg commit -u maximilianou@gmail.com -m 'initial react docker development environment'

14. Updating the repository, with push.

educacion@educacion:~/src/docker13react_initial$ hg push