Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to complete the examples #1

Open
wants to merge 10 commits into
base: broken-examples
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added examples/1/cat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/1/cat2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/1/cat3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/1/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ h1 {
padding: 30px;
}
p {
colour: blue; /* Hint: CSS is written in American English... */
color: blue;
text-align: center;
}
.thirds {
Expand Down
4 changes: 2 additions & 2 deletions examples/1/index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<html>
head>
<head>
<link href="index.css" rel="stylesheet" />
</head>
<body>
h1>Hello World!</h1>
<h1>Hello World!</h1>
<p>Hello to all of the cool cats!!!</p>
<div class="thirds">
<img src="cat.jpg" />
Expand Down
6 changes: 3 additions & 3 deletions examples/1/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const a = 1
a = 2
console.log(a) // Should print 2
console.log(a)

const arrowFcn = a, b => a + b
const arrowFcn = (a, b) => a + b
console.log(arrowFcn(1, 2))

setTimeout(console.log('Hello'), 1500) // Should print 'hello' after 1.5 seconds not immediately
setTimeout(() => console.log('Hello'), 1500)

16 changes: 4 additions & 12 deletions examples/2/hello-world/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react';
import React, { useState } from 'react';
import './App.css';

const Menu = () => null;
import Menu from "./Menu";

function App() {
const CHANGE_NAME_FUNCTION = () => {};
const name = "DEFAULT NAME";
const [name, changeName] = useState("No-Name");

return (
<div className="App">
Expand All @@ -18,13 +16,7 @@ function App() {
}/>
<h1>Hello {name}</h1>
<p>Name:</p>
<input type="text" onChange={
CHANGE_NAME_FUNCTION
/**
Hint: Replace the `CHANGE_NAME_FUNCTION` handler with your own React _state hook_
which will update the `name` variable.
**/
}/>
<input type="text" onChange={(event) => changeName(event.target.value)}/>
</header>
</div>
);
Expand Down
8 changes: 8 additions & 0 deletions examples/2/hello-world/src/Menu.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.link {
font-family: Arial;
padding: 1rem;
}

.link a {
color: white;
}
10 changes: 10 additions & 0 deletions examples/2/hello-world/src/Menu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import "./Menu.css";

export default ({items}) => {
return <div>{ items.map((item) => (
<span className="link" key={item.name}>
<a href={item.link}>{item.name}</a>
</span>))
}</div>;
}
21 changes: 7 additions & 14 deletions examples/3/hello-website/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { connect } from "react-redux";
import { BrowserRouter as Router } from "react-router-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";

import './App.css';

Expand All @@ -11,9 +11,7 @@ const SmallBear = () => <h2>Welcome to the small bear's home</h2>;
const MiddleSizedBear = () => <h2>Welcome the middle sized bear's home</h2>;
const BigBear = () => <h2>Welcome the big bear's home</h2>;

const color = "#fff"; /* Delete this once you've connected to the state */

function App() {
function App({ color }) {
const pages = [
{ path: "/", name: "Home", component: Home },
{ path: "/smallBear", name: "Small Bear", component: SmallBear },
Expand All @@ -27,23 +25,18 @@ function App() {
<h1 className="title" style={ { color } }>Hello Website!</h1>
<Header pages={ pages } />

{ pages.map(({ path, component }) => {
/* Note: We have created a map on configuration constant `pages` to save you time */
{ pages.map(({ name, path, component }) => {
const ifExact = path === "/" ? { exact: true } : {};
/*
Note: We added the `ifExact` constant below to automatically add the `exact` key to the XML when
referring to home, since otherwise it will match all the other pages too - make sure to use
this constant in your Route. You can experiment with alternative solutions to this problem/
*/

/* Add react-router-dom `Route` components for each page */ return null;
return <Route key={ name } path={ path } component={ component } { ...ifExact } />
})
}
</div>
</Router>
);
}

const mapStateToProps = (state) => ({});
/* Connect this component to the Redux state replacing the color constant with the Redux color state as a prop */
const mapStateToProps = (state) => ({
color: state.color
});
export default connect(mapStateToProps)(App);
7 changes: 3 additions & 4 deletions examples/3/hello-website/src/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { connect } from "react-redux";

import "./Header.css";
import Menu from "./Menu";
import { colorChangeAction } from "./actions/color.action";

const colorChange = () => null; /* Delete this once you've connected to the state */

export const Header = ({ pages }) => <header className="App-header"> /* Don't forget the prop */
export const Header = ({ pages, colorChange }) => <header className="App-header">
<Menu items={ pages }/>
<div className="colorPicker">
<label htmlFor="color">Pick font color </label>
Expand All @@ -15,7 +14,7 @@ export const Header = ({ pages }) => <header className="App-header"> /* Don't fo
</header>;

const mapDispatchToProps = (dispatch) => ({
/* Connect your component to the Redux dispatch here */
colorChange: (event) => dispatch(colorChangeAction(event.target.value))
});

export default connect(null, mapDispatchToProps)(Header);
9 changes: 6 additions & 3 deletions examples/3/hello-website/src/Menu.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import React from 'react';
import { Link } from "react-router-dom";
import { connect } from "react-redux";

import "./Menu.css";

export const Menu = ({ items }) => <ul className="menu">
export const Menu = ({ items, color }) => <ul className="menu">
{ items.map(({ path, name }) =>
<li key={ name }>{ /* Add your Link implementation here! Don't forget to color it appropriately. */ }</li>
<li key={ name }>
<Link to={ path } style={ { color } }>{ name }</Link>
</li>
)
}
</ul>

const mapStateToProps = (state) => ({
/* Connect this component to the Redux state passing the Redux color state as a prop used by the links */
color: state.color
});
export default connect(mapStateToProps)(Menu);
5 changes: 4 additions & 1 deletion examples/3/hello-website/src/actions/color.action.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export const COLOR_CHANGE = "COLOR_CHANGE";

export const colorChangeAction = (payload) => ({}); /* Implement this */
export const colorChangeAction = (payload) => ({
type: COLOR_CHANGE,
payload
});
5 changes: 4 additions & 1 deletion examples/3/hello-website/src/reducers/color.reducer.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { COLOR_CHANGE } from "../actions/color.action";

const INITIAL_STATE = "#fff";

export const colorReducer = (previousState = INITIAL_STATE, action) => {
switch (action.type) {
/* Add a case for your COLOR_CHANGE action here */
case COLOR_CHANGE:
return action.payload;

default:
return previousState;
Expand Down
6 changes: 2 additions & 4 deletions examples/4/hello-website/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { connect } from "react-redux";
import './App.css';
import Content from "./Content";

const title = "Welcome!" /* Delete this once you've connected to the state */

function App() {
function App({ title }) {
return (
<div className="App">
<h1 className="title">{ title }</h1>
Expand All @@ -16,6 +14,6 @@ function App() {
}

const mapStateToProps = (state) => ({
/* Connect this component to the Redux state replacing the title constant with the Redux title state as a prop */
title: state.text
});
export default connect(mapStateToProps)(App);
7 changes: 3 additions & 4 deletions examples/4/hello-website/src/Content.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ import React from 'react';
import { connect } from "react-redux";

import "./Content.css";

const goldilocksIsComing = () => null; /* Delete when you implement the dispatch replacing this */
const resetText = () => null;
import { goldilocksAction, resetAction } from "./actions/text.action";

export const Content = ({ goldilocksIsComing, resetText }) => <div className="content">
<button onClick={ goldilocksIsComing }>Goldilocks is coming</button>
<button onClick={ resetText }>Reset title text</button>
</div>;

const mapDispatchToProps = (dispatch) => ({
/* Connect your component to the Redux dispatch here */
goldilocksIsComing: () => dispatch(goldilocksAction()),
resetText: () => dispatch(resetAction())
});

export default connect(null, mapDispatchToProps)(Content);
Expand Down
20 changes: 13 additions & 7 deletions examples/4/hello-website/src/actions/text.action.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ const apiAction = (name) => ({
export const GOLDILOCKS_ACTION = apiAction("GOLDILOCKS_ACTION");
export const RESET_ACTION = "RESET_ACTION";

/*
Note that we have added a new function called asyncAction.
This allows you to define a cleaner interface for API calls.
You will use this _instead_ of the *meta* field suggested in the slides.
*/
export const goldilocksAction = () => ({}); /* Implement this action */
export const goldilocksAction = () => ({
type: GOLDILOCKS_ACTION,
payload: {
method: "GET",
path: `https://www.foaas.com/off/Goldilocks/Three Little Bears`,
headers: new Headers({
"Accept": "application/json"
})
}
});

export const resetAction = () => ({}); /* Implement this action */
export const resetAction = () => ({
type: RESET_ACTION
});
31 changes: 14 additions & 17 deletions examples/4/hello-website/src/middleware/apiRequest.middleware.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
export const apiRequestMiddleware = ({ dispatch }) => next => (action) => {
/*
At this point you have everything hooked up,
but there's one big piece missing - the middleware.
If you play with your app right now,
you'll see that the reset button should work,
but that the `Goldilocks is coming` button will simply trigger an action with a type that is an object.
This isn't correct.
What you need to do is to trap actions that have `apiRequest` set to true within on their type,
launch this request with `fetch` as shown in the slides,
dispatching an action of type `type.PENDING` while the API call is made with the starting payload and
then launching an action of type `type.SUCCESS` with the results of the JSON call.
const { type, payload } = action;
if (type.apiRequest) {
fetch(payload.path, {
method: payload.method,
headers: payload.headers
}).then((rawResult) => rawResult.json()).then((payload) => dispatch({
type: type.SUCCESS,
payload
})).catch((err) => console.log(err));

Don't forget that actions which are not `apiRequest` still need to be passed along to the next middleware
using `next(action)`.

Sidenote: This is JS, we don't care that most of the time `type` is a string and not an object
*/
next(action);
const pendingAction = { ...action, type: type.PENDING };
next(pendingAction);
} else {
next(action);
}
}
11 changes: 10 additions & 1 deletion examples/4/hello-website/src/reducers/text.reducer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { GOLDILOCKS_ACTION, RESET_ACTION } from "../actions/text.action";

const INITIAL_STATE = "Welcome to the three bear's house";
const PROCESSING = "PROCESSING...";

export const textReducer = (previousState = INITIAL_STATE, action) => {
switch (action.type) {
/* Implement the action handlers for `GOLDILOCKS_ACTION.PENDING`, `GOLDILOCKS_ACTION.SUCCESS` and `RESET_ACTION` */
case GOLDILOCKS_ACTION.PENDING:
return PROCESSING;

case GOLDILOCKS_ACTION.SUCCESS:
return `${action.payload.message} ${action.payload.subtitle}`;

case RESET_ACTION:
return INITIAL_STATE;

default:
return previousState;
Expand Down