Skip to content

Commit

Permalink
Exercises 5 and 6 wrap up
Browse files Browse the repository at this point in the history
  • Loading branch information
nikolov1618 committed Sep 26, 2018
1 parent e845e37 commit b4eb433
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 86 deletions.
4 changes: 2 additions & 2 deletions src/exercise_4/Todo.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Tasks:
// 1. Wire up the onClick event handler(line 26) with the callback that is received via props from the parent component.
// 1. Wire up the onClick event handler(line 11) with the callback that is received via props from the parent component.

import React from 'react';

const Todo = props => {
// Hint - you will need to use something from the props for the callback on line 11.
// Hint - you will need to use something from the props for the callback.
const { title, completed } = props.todo;

return (
Expand Down
8 changes: 2 additions & 6 deletions src/exercise_5/Todo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Tasks:
// 1. Wire up the onClick event handler(line 26) with the callback that is received via props from the parent component.

import React from 'react';

const renderTitle = title => {
Expand All @@ -19,11 +16,10 @@ const renderStatus = status => {
}

const Todo = props => {
// Hint - you will need to use something from the props for the callback on line 11.
const { title, completed } = props.todo;
const { title, completed, id } = props.todo;

return (
<div className='todo' onClick={ () => null }>
<div className='todo' onClick={ () => props.onClickHandlerThatWeNeedToWrite(id) }>
{ renderTitle(title) }
{ renderStatus(completed) }
</div>
Expand Down
53 changes: 8 additions & 45 deletions src/exercise_5/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
// Tasks:
// 1. Finish the componentDidMount method implementation.
// 2. Update the state when a new todo is added(rewrite line 54).
// 3. Make sure that you can toggle the state of each todo separately from completed to pending and vice versa(line 63).
// 4. You will also need to check the callback that we are passing to the Todo component(line 90). This is a tough one.

import React, { Component } from 'react';
import Todo from './Todo';

class Exercise_4 extends Component {
class Exercise_5 extends Component {
constructor(props) {
super(props);

// Here we initialize the todos's empty array which we will later fill from the API call.
// We also have the newTodoTitle - a piece of the state that will be used for the input field.
this.state = {
todos: [],
newTodoTitle: ''
todos: []
};
}

Expand All @@ -27,63 +22,31 @@ class Exercise_4 extends Component {
// We use a sample public API that returns mock data.
fetch(urlToFetchFrom)
// We make sure that the response is in JSON data format prior to using the data.
.then(response => response.json())
// You need to cast the response to json by using the .json() method and return the result.
.then(response => null)
// We now set this.state.todos to be the API's response.
// We use the setState({}) syntax in order to comply with React's immutability recommendations.
.then(todos => {
console.log('The fetched todos are:', todos);
});
}

handleSubmit = event => {
event.preventDefault();

const newTodo = {
// This returns an unique datestamp that we use for ID.
id: Date.now(),
// We read the title from our component's state.
title: this.state.newTodoTitle,
// Setting the completed flag to be false by default.
completed: false
}

// Note: React will only know you've updated the state if there is a difference in the state references,
// so we should not mutate the state object(we must return a new object).
// That is why we use the this.setState() method for updating our state. You need to put the new todo in the this.state.todos collection.
// We may use the fancy ES6 spread syntax [...collection, newItem] which adds a new item to a collection.
console.log('New Todo submitted', newTodo);
}

toggleTodoState = id => {
// In the two rows below we clone the todos from the state and then find the clicked todo. We need to flip its completed flag.
const newTodos = [ ...this.state.todos ];
const toggledTodo = newTodos.find(todo => todo.id === id);

// Flip the completed flag and rewrite it in the this.state.todos array. Use ...newTodos - the spread ES6 operator.
console.log('This Todo was toggled', toggledTodo);
toggledTodo.completed = !toggledTodo.completed;

this.setState({ todos: newTodos });
}

render() {
return (
<div>
<h1>Accedia Workshops - ReactJS</h1>

{ /* Note that we are not calling this.handleSubmit(). We are rather passing a reference to it to be used as a callback. */ }
<form onSubmit={ this.handleSubmit }>
{/* Note how we are reading the input value from state and updating the state upon every input field change. */}
{/* By doing this, we always have up-to-date information in our state that we can easily use later. */}
<input
value={ this.state.newTodoTitle }
onChange={ event => this.setState({ newTodoTitle: event.target.value }) }
/>

<input type="submit" />
</form>

<div className="todos-container">
{ this.state.todos.map(currentTodo =>
// Note how we are again passing the toggleTodoState call as a callback rather than invoking the function directly.
// You need to check ./Todo.js and see how to handle the onClickHandlerThatWeNeedToWrite callback that we are passing.
<Todo
key={ currentTodo.id }
todo={ currentTodo }
Expand All @@ -96,4 +59,4 @@ class Exercise_4 extends Component {
}
}

export default Exercise_4;
export default Exercise_5;
11 changes: 2 additions & 9 deletions src/exercise_6/Todo.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
// Tasks:
// 1. Wire up the onClick event handler(line 26) with the callback that is received via props from the parent component.

import React from 'react';

const renderTitle = title => {
// Note that we are using a common remote data handling pattern here.
// If the data has not arrived yet, we return nothing, once it is here, we return the suitable content.
if (title === undefined) return;

return <div>Title: { title }</div>;
}

const renderStatus = status => {
// Once again, we see the same pattern from the renderTitle method.
if (status === undefined) return;

return <span>{ status ? 'V' : 'X' }</span>;
}

const Todo = props => {
// Hint - you will need to use something from the props for the callback on line 11.
const { title, completed } = props.todo;
const { title, completed, id } = props.todo;

return (
<div className='todo' onClick={ () => null }>
<div className='todo' onClick={ () => props.onClickHandlerThatWeNeedToWrite(id) }>
{ renderTitle(title) }
{ renderStatus(completed) }
</div>
Expand Down
39 changes: 15 additions & 24 deletions src/exercise_6/index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,40 @@
// Tasks:
// 1. Finish the componentDidMount method implementation.
// 2. Update the state when a new todo is added(rewrite line 54).
// 3. Make sure that you can toggle the state of each todo separately from completed to pending and vice versa(line 63).
// 4. You will also need to check the callback that we are passing to the Todo component(line 90). This is a tough one.
// 1. Complete the handleSubmit method implementation.

import React, { Component } from 'react';
import Todo from './Todo';

class Exercise_4 extends Component {
class Exercise_6 extends Component {
constructor(props) {
super(props);

// Here we initialize the todos's empty array which we will later fill from the API call.
// We also have the newTodoTitle - a piece of the state that will be used for the input field.
// We have the newTodoTitle below - a piece of the state that will be used for the input field.
this.state = {
todos: [],
newTodoTitle: ''
};
}

componentDidMount() {
// Here is the full url that we need to fetch data from.
const urlToFetchFrom = 'https://jsonplaceholder.typicode.com/todos?_limit=5';

// Fetch is a built in XHR(AJAX) client with a Promise based API - basically we send a get request.
// We use a sample public API that returns mock data.
fetch(urlToFetchFrom)
// We make sure that the response is in JSON data format prior to using the data.
.then(response => response.json())
// We now set this.state.todos to be the API's response.
// We use the setState({}) syntax in order to comply with React's immutability recommendations.
.then(todos => {
console.log('The fetched todos are:', todos);
this.setState({ todos });
});
}

handleSubmit = event => {
// We prevent the default browser behaviour upon submitting a form.
event.preventDefault();

// Below we construct the new todo that we will be adding.
const newTodo = {
// This returns an unique datestamp that we use for ID.
id: Date.now(),
// We read the title from our component's state.
title: this.state.newTodoTitle,
// You need to appropriately update the new todo's title.
title: null,
// Setting the completed flag to be false by default.
completed: false
}
Expand All @@ -52,15 +44,18 @@ class Exercise_4 extends Component {
// That is why we use the this.setState() method for updating our state. You need to put the new todo in the this.state.todos collection.
// We may use the fancy ES6 spread syntax [...collection, newItem] which adds a new item to a collection.
console.log('New Todo submitted', newTodo);

// Finally, once we have updated our todos, we clean the form's input field.
this.setState({ newTodoTitle: '' });
}

toggleTodoState = id => {
// In the two rows below we clone the todos from the state and then find the clicked todo. We need to flip its completed flag.
const newTodos = [ ...this.state.todos ];
const toggledTodo = newTodos.find(todo => todo.id === id);

// Flip the completed flag and rewrite it in the this.state.todos array. Use ...newTodos - the spread ES6 operator.
console.log('This Todo was toggled', toggledTodo);
toggledTodo.completed = !toggledTodo.completed;

this.setState({ todos: newTodos });
}

render() {
Expand All @@ -76,14 +71,10 @@ class Exercise_4 extends Component {
value={ this.state.newTodoTitle }
onChange={ event => this.setState({ newTodoTitle: event.target.value }) }
/>

<input type="submit" />
</form>

<div className="todos-container">
{ this.state.todos.map(currentTodo =>
// Note how we are again passing the toggleTodoState call as a callback rather than invoking the function directly.
// You need to check ./Todo.js and see how to handle the onClickHandlerThatWeNeedToWrite callback that we are passing.
<Todo
key={ currentTodo.id }
todo={ currentTodo }
Expand All @@ -96,4 +87,4 @@ class Exercise_4 extends Component {
}
}

export default Exercise_4;
export default Exercise_6;

0 comments on commit b4eb433

Please sign in to comment.