Category Archives: Uncategorized

Object Types

In many cases returning a scalar values like Int or String might not be enough and we might want to return more complex data, like Objects. Let’s modify our previous example to do this.

Adding type object into GraphQL’s schema.

Objects could be defined in the schema the same way as we defined the Query (lines 4-7) and then we could modify greetingUser Query to return our new object: greeting instead of String 

...
var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);
...

Once we have the new greeting type into the schema we could write the resolver, which could be a plain Java Script object object (in our case a function that returns the exposed methods):

...
var greeting = (userName) => {

  function rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  function userRollDice(args) {
    return `User ${args.userName} rolled: ${rollDice()}`;
  }
  return  {
    userName: userName,
    userRollDice: userRollDice
  }
}
...

what we just did:
– we created a new method called greeting which exposes one string property named userName, that we are passing and one method called userRollDice which will return String which will describe (in plain text) what dice # the used rolled.
– we also added a helper method called rollDice which will return a random number.

The whole code should look like this:

./server.js

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language

var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);

var greeting = (userName) => {
  
  function rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  function userRollDice(args) {
    return `User ${args.userName} rolled: ${rollDice()}`;
  }
  return  {
    userName: userName,
    userRollDice: userRollDice
  }
}


// The root provides a resolver function for each API endpoint
var root = {
  greetingUser: (args) => {
    return greeting(args.userName);
  }
};

var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4001);
console.log('Running a GraphQL API server at localhost:4000/graphql');

Let’s give it a try. Using the Document explorer click on Query and you will see that there is a query named greetingUser, that expects userName string, and returns the new method greeting.

greetingUser(userNameString!): greeting

Explore the greeting and you will see that it could be queried for userName and userRollDice which also expects one string parameter.

userRollDice(userNameString): String
Having this information we are ready to construct our new query. Add the code below in GraphQL UI’s query box (up left)
query queryLabel($userName: String!) {
  greetingUser(userName: $userName){
    userName
    userRollDice(userName: $userName)
  }
}

and leave the parameter box (down left) the same for now.

{
  "userName": "Sam Smith"
}

Hitting play will produce a nice response like this:

{
  "data": {
    "greetingUser": {
      "userName": "Sam Smith",
      "userRollDice": "User Sam Smith rolled: 4"
    }
  }
}

GraphQL just returned us the greeting object that we requested.

Using ES6 features.

Let’s modify the resolver to use ES6 class syntax and also let’s add a destructors to clean up the code a bit.

./server.js

var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language

var schema = buildSchema(`

  type greeting {
    userName: String
    userRollDice(userName: String): String
  }

  type Query {
    greetingUser(userName:String!): greeting
  }
`);

class greeting {
  
  constructor(userName) {
    this.userName = userName;
  }
  
  rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }  
    
  userRollDice({userName}) {
    return `User ${userName} rolled: ${this.rollDice()}`;
  }
}


// The root provides a resolver function for each API endpoint
var root = {
  greetingUser: ({userName}) => {
    return new greeting(userName);
  }
};

var app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));
app.listen(4001);
console.log('Running a GraphQL API server at localhost:4000/graphql');

 what we just did:
– we replaced the JavaScript function resolver with class having the same methods.
– in userRollDice method we replaced args.userName with the destructor {userName}
– in the root resolver we call greetingUser, passing the userName and returning new instance of greeting

Adding Redux

branch-name:  
Click To Copy

 

In the previous tutorial we showed how to build custom Redux like store, which is a great way to understand how Redux work, but if we want a production grade app, we have to do more work on our custom Redux like store, since we cheated a bit.

For example our redux store emits setState no matter if the properties are actually changed or not which is ok for a demo app but for a big app with a lot of mapStateToProps it will have performance impact, so let’s not re-invent the wheel but use the Redux store instead.

yarn add redux react-redux

Since Redux like implementation that we did in the previous tutorial is very similar to the actual Redux, there are just a few changes that we need to do in order to start using Redux.

./src/components/App/index.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import PageLayout from '../../containers/PageLayout';
import { Provider } from 'react-redux';
import { createStore} from 'redux';
import reducers from '../../reducers';

import fetch from 'unfetch';


const store = createStore(reducers, {});

export default class App extends Component {

  render() {

    const GRAPHQL_URL = 'http://localhost:4001/graphql';
    const client = new ApolloClient({
      link: new HttpLink({ uri:  GRAPHQL_URL, fetch: fetch }),
      cache: new InMemoryCache()
    });  

    return (
      <Provider store={store}>
        <ApolloProvider client={client}>
          <Router>
            <Switch>
              <Route exact path="*" component={PageLayout} />    
            </Switch>
          </Router>
        </ApolloProvider>
      </Provider>
    );
  }
}

 what we just did:
– we removed our custom store implementation:

import Store from ‘../../store’;
import Reducers from ‘../../reducers’;
import Provider from ‘../../containers/Provider’;


– and replaced it with the Redux provider and create store (line 8 and 9)
– we called the Redux createStore (line 15)
– finally we wrapped the app with the new provider passing the store (line 28)

Next step is just cleaning up the code a bit.
– We renamed the index.js reducer to ./src/reducers/useer.js so we could keep each different reducer types in separate files and we added one main reducer ./src/reducers/index.js that will combine all other reducers. (in our case ./src/reducers/useer.js for now)

./src/reducers/user.js

const CHANGE_USERNAME = 'CHANGE_USERNAME';
const TOGGLE_EDIT_MODE = 'TOGGLE_EDIT_MODE';

const initialState = {
  todos: [],
  userName: "No Name",
  editMode: false
};

  const reducer = (state = initialState, action) => {
    switch (action.type) {
      case CHANGE_USERNAME: {
        let newState = {...state};
        newState.userName = action.data;
        return newState;
      }

      case TOGGLE_EDIT_MODE: {
        let newState = {...state};
        newState.editMode = !newState.editMode;
        return newState; 
      }

      default:
        return state;
    }
  };

export default reducer;

 

./src/reducers/index.js

import { combineReducers } from 'redux';
import user from './user';

export default combineReducers({
  user
});

 

And the best part is that since our Redux like implementation was so similar to the actual Redux implementation, we have to make just two little changes:
– Replace import connect from '../../containers/Provider/connect'; with the Redux connect import { connect } from 'react-redux';
– And since we added combineReducers we have to add user property to access the users reducer.

./src/components/About/index.js ./src/components/Greetings/index.js.

import React, { Component } from 'react';
import { connect } from 'react-redux';

const styles = require('./styles.scss');

const CHANGE_USERNAME = 'CHANGE_USERNAME';
const TOGGLE_EDIT_MODE = 'TOGGLE_EDIT_MODE';

class Greetings extends Component {

  constructor(props) {
    super(props); 
  }
  

  doneEditUsername() {
    let newName = document.querySelector('#inputField').value;
    this.props.changeUserName(newName);
    this.props.toggleLogInPopup();
  }

  usernameChanged(el) {
    let newName = el.target.value;    
    this.props.changeUserName(newName);
  }

  onToggleEditMode() {
    this.props.toggleLogInPopup();
  }

  render() {
    let element = <h2 onClick={() =>{   this.onToggleEditMode()  }}>Hello:  {this.props.userName}</h2>;
    if(this.props.editMode)
      element = <h2>Type new name:<input type="text" id='inputField' value={this.props.userName} onChange={(el) => { this.usernameChanged(el);}} /><button onClick={() =>{ this.doneEditUsername() }}>done</button></h2>
    return (
      <div>
        <div className={styles.wrapper}>
          {element}
        </div>
      </div>);
  }
}

const mapStateToProps = ( storeState ) => {
  return {  
    userName: storeState.user.userName,
    editMode: storeState.user.editMode
  }
}

const mapDispatchToProps = dispatch => {
  return {
    toggleLogInPopup: () => {
      dispatch({type: TOGGLE_EDIT_MODE});
    },
    changeUserName: (userName) => {
      dispatch({type: CHANGE_USERNAME, data: userName});
    }
  }
};


export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Greetings);

 

./src/components/About/index.js ./src/components/About/index.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

const CHANGE_USERNAME = 'CHANGE_USERNAME';
class About extends Component {
  constructor(props) {
    super(props);
    this.state = {
      userName: this.props.userName,
    };    
  }
  handleChange() {
    const userName = document.querySelector('input[name=username]').value;
    this.setState( { userName: userName } );
    this.props.onEdit(userName);
  }
  render() {
    return (
      <div>
        <p>This is <input type="text" name="username" value={this.state.userName} onChange={() => { this.handleChange()}} /></p>
      </div>
    );
  }
}
//export default About;
const mapStateToProps = storeState => ({
  userName: storeState.user.userName
}
);
const mapDispatchToProps = dispatch => ({
  onEdit: (userName) => dispatch({
    type: CHANGE_USERNAME,
    data: userName
  })
});
const AboutContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(About);
export default AboutContainer;

 

And delete ./src/containers/Provider folder.

And now all custom Redux like implementation was replaced wit the actual Redux store. Give it a try and everything shoul;d work like before but using the actual Redux store.

 

branch-name:  
Click To Copy

 

Max Consecutive Ones

Task

Given a binary array, find the maximum number of consecutive 1s in this array.

Example 1:

Input: [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
    The maximum number of consecutive 1s is 3.

Note:

  • The input array will only contain 0 and 1.
  • The length of input array is a positive integer and will not exceed 10,000

Solution

The solution:

/**
 * @param {number[]} nums
 * @return {number}
 */
var findMaxConsecutiveOnes = function(nums) {
    var count = 0;
    var last = 0;
    for(var c in nums) {
        if(nums[c])
            count ++;
        else {
            if(count > last)
                last = count;
            count = 0;
        }
    }
    return Math.max(count, last);
};

 

Plus One

Task

Given a non-empty array of digits representing a non-negative integer, plus one to the integer.

The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.

You may assume the integer does not contain any leading zero, except the number 0 itself.

Example 1:

Input:

 [1,2,3]

Output:

 [1,2,4]

Explanation:

 The array represents the integer 123.

Example 2:

Input:

 [4,3,2,1]

Output:

 [4,3,2,2]

Explanation:

 The array represents the integer 4321.

This problem was taken from Leetcode

Solution

The solution:

The solution is pretty straight forward. We traverse all digits in the opposite direction, and make sure that we add +1 only on the last digit (the first iteration ). Then if the digit > 9 we set up the dit to 0, and we carry on 1 to add it to the next digit, and keep going till we reach the first digit. If the first digit is 9 and cary over is not 0, we add 1 to the beginning of the array.

let’s consider: 9 9 9

iteration 1:
9            9
9            9
9 + 1 =  0 + cary on: 1

iteration 2:
9            9
9 + 1 =  0 + cary on: 1
0            0

iteration 3:
9 + 1 = 0 + cary on: 1
0          0
0          0

finally:
1     << adding leading 1 
0
0
0

which gave up the final result: 1 0 0 0

The solution will look like this:

Java Script

/**
 * @param {number[]} digits
 * @return {number[]}
 */
var plusOne = function(digits) {
    
    var carryOn = 0;
    for(q = digits.length - 1; q!=-1; q--) {
        var digit = digits[q];
        if(q == digits.length - 1) {
            digit = digit + 1;
            if(digit == 10) {
                digit = 0;
                carryOn = 1;
            }
        }
        else {
            if(digit == 9 && carryOn) {
                digit = 0;
            }
            else {
                digit = digit + carryOn;
                carryOn = 0;
            }
        }
        digits[q] = digit;
    }
    if(carryOn > 0) 
        digits.unshift(1);
    return digits;
};

 

what we just did:
– (lines 11 – 18) happened only if this is the last digit, where we have to add 1
– (lines 18 – 20) if we have carry on value of carryOn > 0 and digit = 9 simply set digit = 0 and left carryOn to be equal to 1 for the next iteration.

Valid Parentheses

Task

Given a string containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.

Note that an empty string is also considered valid.

Example 1:

Input:

 "()"

Output:

 true

Example 2:

Input:

 "()[]{}"

Output:

 true

Example 3:

Input:

 "(]"

Output:

 false

Example 4:

Input:

 "([)]"

Output:

 false

Example 5:

Input:

 "{[]}"

Output:

 true

This problem was taken from Leetcode

Solution

The solution:

Let’s look at the simplest scenario where we have only one type of brackets: ‘(‘ and ‘)’. Then all that we need to do in order to figure out if each bracket has corresponding closing bracket is to put each opening bracket into a stack, and pop one bracket when we see closing bracket.

Ideally if the brackets are “normalized” (all of the open one have corresponding closing brackets) we will end up with empty stack.

in example :

( ( ) ( ) ( ( ) ) )
1 2  3  4 5  6  7  8  9  10

so here are all 10 steps:

steps  stack
1          (
2          (  (
3         (
4         (  (
5         (
6         (  (
7         (  (  (
8         (  (
9         (
10

Immediately it becomes clear that if the string  length is not an even number, it automatically becomes invalid. So we could do this check in the very beginning (lines 9 and 10)  below.

So let’s look at the current example where we have 3 different tags: ‘{}’, ‘()’, ‘[]’

The rule for a valid string is:
open tags:
– we could have as many open tag as we want. i.e. : ({[[ ...
closing tags:
– every closing tag should match previously opened tag ([]) – valid, ([)] – invalid.

So now we know the rules, let’s write the code.

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    
    var input = s.split('');
    
    if(input.length % 2 != 0)
        return false;
    
    var stack = [];

    var tagIndex = {
        '(': 0,
        ')': 1,
        '{': 2,
        '}': 3,
        '[': 4,
        ']': 5
    };        


    for(var q=0;q < input.length; q++) {
        var symbol = input[q];
        var tagType = (tagIndex[symbol] % 2); // 0 - open, 1 - close
        if(tagType == 0) {
            stack.push(symbol);
        }
        else {
            // this is a closing tag, make sure that it follows the rules
            lastTag = stack.pop();            
            lastTagIndex = tagIndex[lastTag];
            if( tagIndex[symbol] != lastTagIndex + 1 )
                return false;
        }
    }
    
    if(stack.length > 0)
        return false;
    return true;
};

 

what we just did:
– lines 9 and 10: we check if the length of the string is odd and return false immediately if so.
– we added tagIndex object where every bracket has it’s index which will help us to identify if we have the open or closing bracket.
– If it is open bracket, we just putting it inside the stack.
– if this is a close bracket, we are using the newly created  tagIndex to figure out if this is the right closing bracket from the same type. Simply following the rule that we described above (lines 32 -35)  `if( tagIndex[symbol] != lastTagIndex + 1 )` Basically we check if the previous opening tag in the stack is of the same type of the current closing tag.

Adding dynamic page layout loaded from GraphQL

branch-name:  
Click To Copy

 

Having page layout hardcoded works fine but it doesn’t let us dynamically modify it without changing the code. What about if we store the page layout in mongoDB, then request it through GraphQL and create component that could dynamically load the page components.

Luckily for us we already have page layout set up in GraphQL which for the homepage looks like this:

module.exports = [
    {
      id: 'home',
      url: '/home',
      layout: [ 
        {
          span: 12,
          components: [
            {
              name: "Header"
            }
          ]
        },
        {
          span: 12,
          components:[
            {
              name: "Home"
            }
          ] 
        }                       
      ]
    }
  ]

It simply shows that the page layout has a header and Home component. We are going to build component that will interpret this and will render a webpage with the requested components. This way we will have the flexibility to:

  • dynamically change page layout by adding and removing components without code change
  • create new pages on the fly without code change.

And if you want to explore all other layouts you could look into GraphQL project under ./src/models/mock_data/pages

Creating PageLayout component to load our modules.

Let’s change App/index.js remove all other routes and redirect everything to the new component that we are going to create (line 21).

./src/components/App/index.js

import React, { Component } from 'react';
import PageLayout from '../../containers/PageLayout';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import styles from './styles.scss';
export default class App extends Component {
  render() {
    const GRAPHQL_URL = 'http://localhost:4001/graphql';
    const client = new ApolloClient({
      link: new HttpLink({ uri:  GRAPHQL_URL }),
      cache: new InMemoryCache()
    });  
    return (
      <div className={styles.appWrapper}>
        <ApolloProvider client={client}>
          <Router>
            <Switch>
            <Route exact path="*" component={PageLayout} />  
            </Switch>
          </Router>
        </ApolloProvider>
      </div>        
    );
  }
}

Now let’s continue with creating the component itself.

./src/containers/PageLayout/index.js

import React, { Component } from 'react';
import query from './query';
import { graphql } from 'react-apollo';

class PageLayout extends Component {

    constructor(props) {
      super(props);      
    } 
  
    render() {
        console.log(this.props.data.getPageByUrl);
        return (
        <div>
            this is my page layout!
        </div>
        );
    }
}

export default graphql(query, {
    options(props) {
      return {
        variables: {
          url: props.history.location.pathname
        },
      };
    },
  })(PageLayout);

./src/containers/PageLayout/query.js

import gql from 'graphql-tag';

const query = gql`
query getPageByUrl($url: String) 
{
  getPageByUrl(url: $url) {
    id
    url
    layout {
      span
      components {
        name
      }        
    }
  }
}
`
export default query;

and when you run the project and look at the browser console you will see the layout structure that we printed out in index.js (line 12)

This basically describes which components and in what order should be rendered for the ‘home’ page.

Hook PageLayot component to render required HTML components.

Create ComponentList sub component with the following contents:

./src/containers/PageLayout/ComponentList/index.js

import Header from '../../../components/Header';
import Home from '../../../components/Home';
import About from '../../../components/About';
import Greetings from '../../../components/Greetings';
import Gallery from '../../../containers/DogsCatalog';

export default {
  Home: Home,
  About: About,
  Greetings: Greetings
}

This component simply provide a list of all components that we are going to render in our website.

Now modify PageLayout component to add the list and render the HTML components.

./src/containers/PageLayout/index.js

import React, { Component } from 'react';
import ComponentList from './ComponentList';
import query from './query';
import { graphql } from 'react-apollo';

const styles = require('./styles.scss');

class PageLayout extends Component {

    constructor(props) {
      super(props);      
    } 
  
    render() {
      if(!this.props.data.getPageByUrl) {
        return(<p>loading ...</p>);
      }     
      
      const allLayout = this.props.data.getPageByUrl.layout.map((layoutList) => {
        const layout = layoutList.components.map((component, id , components) => {
          const componentName = component.name;        
          const ChildComponent = ComponentList[componentName];
          if(typeof ChildComponent === 'undefined') {
            return(
              <div key='{id}' className={styles.error}>Can't find {componentName} component!</div>
            );
          }
          return (
              <ChildComponent key={componentName} />
          );
        });
        return layout;
      });
      return(allLayout);
    }
}

export default graphql(query, {
    options(props) {
      return {
        variables: {
          url: props.history.location.pathname
        },
      };
    },
  })(PageLayout);

 what we just did:
– we added the ComponentList which returns all components on our website
– (Line 19) we are getting the layout for this particular url that contains all components, then we loop through all components (line 20) and create an instances for all of them.
– If the component cannot be found it will show red error message (lines 23-27)

Also add the css which will colorize the error message in red:

./src/containers/PageLayout/styles.scss

.error {
  background: red;
  color: white;
}

navigate to http://localhost:8080/home and you are probably going to see this screen:

This is actually made intentional, to demonstrate how our error handler works If it can’t find particular component.

Let’s fix this. Add the highlighted lines with the missing components.

./src/containers/PageLayout/ComponentList/index.js

import Header from '../../../components/Header';
import Home from '../../../components/Home';
import About from '../../../components/About';
import Greetings from '../../../components/Greetings';
import Gallery from '../../../containers/DogsCatalog';

export default {
  Home: Home,
  About: About,
  Greetings: Greetings,
  DogsCatalogWithRedux: DogsCatalog,
  Header: Header
}

Navigate again to http://localhost:8080/home and you should have SPA with 4 pages.

 

branch-name:  
Click To Copy

 

 

 

Adding navigation in Single Page App

The concept of Single Page App is that all modules will be dynamically rendered while user navigates the page, without reloading. Express routing which we added is providing this functionality for us, so let’s use it.

Adding navigation.

Let’s get started. Edit index.html and add the highlighted line so we will have some marker on the page that will indicate if the page reloads.

./index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Babel Webpack Boilerplate</title>
    </head>
    <body>
        <h3>SPA</h3>
        <div id="root"></div>
        <script type="text/javascript" src="dist/main-bundle.js"></script>
    </body>
</html>

 

Create header menu for navigation.

Let’s create new navigation component and call it Header component. Create new folder ./src/components/Header and add:

./src/components/Header/index.js

import React from 'react';
import { Link } from 'react-router-dom';

const styles = require('./styles.scss');

const Header = ( {title} ) => (
  <div>
    <h2>{ title }</h2>
    <div className={styles.wrapper}>
      <ul>
        <li><Link to='/'>HOME</Link></li>
        <li><Link to='/about'>ABOUT</Link></li>
        <li><Link to='/greetings'>GREETINGS</Link></li>   
        <li><Link to='/gallery'>GALLERY</Link></li>      
      </ul>
    </div>
  </div>
);

export default Header;

also add the CSS

./src/components/Header/styles.scss

.wrapper {
  
  ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    border: 1px solid #e7e7e7;
    background-color: #f3f3f3;
  }
  li {
    float: left;
  }

  li a {
    display: block;
    color: #666;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
  }

  li a:hover:not(.active) {
      background-color: #ddd;
  }

  li a.active {
      color: white;
    
  }
}

Add header menu in our components.

Home component

We added home as a first link but we actually don’t have Home component, so let’s create a simple one and add header navigation there.

create ./src/components/Home folder and add:

./src/components/Home/index.js

import React from 'react';
import Header from '../Header';

const styles = require('./styles.scss');

const Home = () => (
  <div>
    <Header />
    <div className={styles.wrapper}>This is my home section.</div>
  </div>
)

export default Home;

and the css:

./src/components/Home/styles.js

.wrapper {
  background: rgb(141, 141, 172);
  color: white;
  text-align: center;
}

About component.

do the same for About component.

./src/components/About/index.js

import React from 'react';
import Header from '../Header';

const styles = require('./styles.scss');

const About = () => (
  <div>
    <Header />
    <div className={styles.wrapper}>This is the About section.</div>
  </div>
)

export default About;

./src/components/Home/styles.scss

.wrapper {
  background: rgb(141, 141, 172);
  color: white;
  text-align: center;
}

DogsCatalog container component.

and DogsCatalog container component

./src/containers/DogsCatalog/index.js

/* eslint-disable no-debugger */

import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import DogDetails from './DogDetails';
import Header from '../../components/Header';

import query from './query';

const styles = require('./styles.scss');


class DogsCatalog extends Component {

  constructor(props) {
    super(props);
    this.state = {
        breed: "labrador"
    }
  }

  handleClick(breedType) {
    this.setState({
        breed: breedType
    });
  }

  render() {  
    if(typeof this.props.data.getDogsList == 'undefined') {
      return(
        <div>Loading ... </div>
      );
    }
    return(
      <div>
        <Header />
        <div className={styles.Wrapper}>
          <p>Dogs catalog</p>
          <div className={styles.Buttons}>
            {this.props.data.getDogsList.map( (dog) => {
              return (<button key={dog.id} onClick={ () => { this.handleClick(dog.breed) } }>{dog.breed}</button>);
            })}          
          </div>
          <DogDetails breed={this.state.breed} />
        </div>
      </div>
    );
  }
}


export default graphql(query, {})(DogsCatalog);

Greetings component.

./src/components/Greetings/index.js

import React from 'react';
import Header from '../Header';

const styles = require('./styles.scss');

const Greetings = (props) => (
  <div>
    <Header />
    <div className={styles.wrapper}><h2>Hello  {props.user}</h2></div>
  </div>
)



export default Greetings;

Set up the routes.

./src/components/app.index.js

import React, { Component } from 'react';
import Greetings from '../greetings';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import About from '../about';
import Home from '../Home';
import { ApolloProvider, graphql } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import DogsCatalog from '../../containers/DogsCatalog';
import fetch from 'unfetch';

export default class App extends Component {

  render() {

    const GRAPHQL_URL = 'http://localhost:4001/graphql';
    const client = new ApolloClient({
      link: new HttpLink({ uri:  GRAPHQL_URL, fetch: fetch }),
      cache: new InMemoryCache()
    });  

    return (
      <ApolloProvider client={client}>
        <Router>
          <Switch>
            <Route exact path="/" component={Home} />    
            <Route exact path="/About" component={About} />                      
            <Route exact path="/greetings" component={Greetings} />
            <Route exact path="/gallery" component={DogsCatalog} />
          </Switch>
        </Router>
      </ApolloProvider>
    );
  }
}

Basically we told Express which component to render for each route.

Give it a try and fire up the server using your preferred config.

At this point you will have neat SPA (Single Page App) that dynamically renders the components without ever reloading the page.

 

Setting up SSL host using LetsEncrypt free certificate and set up auto renewal shell script.

1. Obtain SSL certificates from the letsencrypt.org ACME server.Navigate to the location that you would like to add the script. I personally prefer to keep apps and scripts here:
cd ~/Applications

2. Download getssl (this is the auto renewal shell script)
git clone https://github.com/srvrco/getssl.git

4. Do initial setup
 ./getssl -c yourdomain.com

this command will create the following folders and files:

~/.getssl
~/.getssl/getssl.cfg
~/.getssl/yourdomain.com
~/.getssl/yourdomain.com/getssl.cfg

5. Edit ~/.getssl/getssl.cfg There are a couple of things that we have to set up:
– make sure that you switch to use the staging server while testing, since the production one has rate limits.

# The staging server is best for testing
CA="https://acme-staging.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
#CA="https://acme-v01.api.letsencrypt.org"

6.Add the sub domains in ~/.getssl/yourdomain.com/getssl.cfg

# Additional domains - this could be multiple domains / subdomains in a comma separated list
# Note: this is Additional domains - so should not include the primary domain.
SANS="www.mysite.com, other.mysite.com"

– Very important: add the location where the script should put verification file in order to prove that you have ownership over this domain. For more information of what exactly is the prove of ownership procedure you could read https://letsencrypt.org/how-it-works/ but basically the bash script puts a small file into specific server directory and then the letsencrypt server checks id the file is there and ensures that you have control over this domain.
So Make sure that this folder (acme-challenge) is accessible on the web.
What that means is that if you put a test text file (e.e. test.txt) with any random text inside in this location: /webroot/.well-known/acme-challenge and then you open the browser and point to www.mysite.com/.well-known/acme-challenge/test.txt you should be able to see the contents of the file.
Once you did this you could go ahead and edit .getssl file and add the right location.

# Acme Challenge Location. The first line for the domain, the following ones for each additional domain.
# If these start with ssh: then the next variable is assumed to be the hostname and the rest the location.
# An ssh key will be needed to provide you with access to the remote server.
# Optionally, you can specify a different userid for ssh/scp to use on the remote server before the @ sign.
# If left blank, the username on the local server will be used to authenticate against the remote server.
# If these start with ftp: then the next variables are ftpuserid:ftppassword:servername:ACL_location
# These should be of the form "/path/to/your/website/folder/.well-known/acme-challenge"
# where "/path/to/your/website/folder/" is the path, on your web server, to the web root for your domain.
#ACL=('/var/www/toninichev.com/web/.well-known/acme-challenge'
#     'ssh:server5:/var/www/toninichev.com/web/.well-known/acme-challenge'
#     'ssh:sshuserid@server5:/var/www/toninichev.com/web/.well-known/acme-challenge'
#     'ftp:ftpuserid:ftppassword:toninichev.com:/web/.well-known/acme-challenge')

ACL=('/var/www/html/projects/src/webroot/.well-known/acme-challenge')

 Make sure that you replace /var/www/html/projects/src/ with the actual location on your server.
– one last thing that I did is to use single ACL to make my life easier

#Set USE_SINGLE_ACL="true" to use a single ACL for all checks
USE_SINGLE_ACL="true"

7. Execute the script and create certificate

~/Applications/getssl yourdomain.com

Again make sure that you navigate to the place where you did git clone of the script.

Example of adding certificate to an express server:

var options = {
    key: fs.readFileSync('/Users/toninichev/.getssl/mysite.com.key'),
    cert: fs.readFileSync('/Users/toninichev/.getssl/mysite.com.crt')
    };

/**
 * HTTP Server
 * Gets post requests from app_clients and sends data to the web_clients
 */
var app = https.createServer(options, function (request, response) {
...
});

Example of adding certificate to Apache virtual host:

<VirtualHost *:443>

    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    ServerAdmin info@mywebsite.com

    SSLEngine on
    SSLCertificateFile /Users/toninichev/.getssl/mywebsite.com/mywebsite.com.crt
    SSLCertificateKeyFile /Users/toninichev/.getssl/mywebsite.com/mywebsite.com.key

    ErrorLog "/private/var/log/apache2/mywebsite.com-error_log"
    CustomLog "/private/var/log/apache2/mywebsite.com-access_log" common

    SetEnv APPLICATION_ENV production
    DocumentRoot "/Users/toninichev/mywebsite/app/webroot"
    <Directory "/Users/toninichev/mywebsite/app/webroot">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

 

 

Two way communication between parent document and iFrame

This page is a simple demonstration of two way communication between iFrame and parent document even if they are hosted in different domains.

index.html

<html>
  <head>
    <style>
      iframe {
      width:50%;
      height:50%;
      }
    </style>

    <script>
      // Listen for iframe loaded event
      window.addEventListener("message", receiveMessage, false);
      function receiveMessage(event)
      {
        if(event.origin !== "http://sandbox.toni-develops.com")
        return
        console.log('[parent]' + event.data);
      }

      function postTheMessage() {
        document.querySelector('#my_iframe').contentWindow.postMessage("Parent doc messaged the iframe", "*");
      }
    </script>
  </head>

  <body>
    <div id="wrapper">
    <iframe id="my_iframe" src="./iframe.html"></iframe>
    <br>
    <button onclick="postTheMessage()">send message to the iframe</button>
    </div>
  </body>
</html>

Two very important notes:
– When we add an event listener, we have to explicitly specify that we are going to listen to a “message” (line 12) and not passing the actual message there.
– we have to declare the event listeners before loading the actual <iframe ..> tag.

 

iframe.html


<html>
<head></head>

<body>
<script>
window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
{
if(event.origin !== "http://mydev.com")
return
console.log('[iframe]' + event.data);
}

function postTheMessage() {
window.parent.postMessage("iFrame sent a message", "http://mydev.com/sandbox/*");
}

postTheMessage();
</script>

<p>I am an iFrame!</p>
<br>
<button onclick="postTheMessage()">click to post message to the parent document</button>

</body>
</html>

 

How this works:
– Parent document index.html is subscribing for events named “message” (line 12) and calls receiveMessage function (line 13) when the event occur.
– When document is loaded, and the iframe is ready, it emits message to index.html (line 19 in iframe.html)
– When parent document receives message, it makes sure that it comes from the domain that the parent document is interested in, so no other iframe could trigger this action (line 15 in index.html) If so, do something. In this case console.log the message.

 

Synchronizing Filezilla site config between all devices.

If you use several computers at work and at home, sometimes becomes quite handy to be able to have all site configs synced automatically instead of importing and exporting it after each change. And this is quite simple to achieve.
Filezilla stores site config in sitemanager.xml file, so all that you need to do is to replace this file with a copy stored in Dropbox, Google Drive or any other file synchronizing service.

  1. Locate sitemanager.xml file on your machine.
    Windows 7/8 & Vista – C:\Users\YourUserName\AppData\Roaming\FileZilla\sitemanager.xml
    Mac OSX – /users/YourUserName/.config/filezilla/sitemanager.xml
    Linux – /home/YourUserName/.filezilla/sitemanager.xml
  2. Create copy of this file to your favorite synchronizing folder: i.e.:\Dropbox\Settings\sitemanager.xml
  3. Create “softlink” (symbolic link) to the new location.
    Windows(open command prompt and type):
    mklink “C:\Users\YourUserName\AppData\Roaming\FileZilla\sitemanager.xml” “C:\Users\YourUserName\Dropbox\Settings\sitemanager.xml”OS X (terminal):
    ln -s /users/YourUserName/Dropbox/Settings/sitemanager.xml /users/YourUserName/.config/filezilla/sitemanager.xml

    Linux (terminal):
    ln -s /home/YourUserName/Dropbox/Settings/sitemanager.xml /home/YourUserName/.filezilla/sitemanager.xml