diff --git a/src/App/App.js b/src/App/App.js
index 08d7334..416587c 100644
--- a/src/App/App.js
+++ b/src/App/App.js
@@ -1,10 +1,13 @@
import React, { Component } from 'react';
-import logo from './logo.svg';
+// import logo from './logo.svg';
import './App.css';
+
+// components
import Product from '../product/product';
+import WishList from '../wishlist/wishlist';
+// services
import HttpService from '../services/http-service';
-
const http = new HttpService();
class App extends Component {
@@ -13,9 +16,9 @@ class App extends Component {
this.state = {products:[]};
//Bind funictions
- this.loadData = this.loadData.bind(this);//the loaddata is bound to here thus referring to this scope rather than refering it to global scope
+ this.loadData = this.loadData.bind(this);//the loaddata is bound here, thus referring to this scope rather than refering it to global scope
this.productList = this.productList.bind(this);
-
+
this.loadData(); //this is where the function is passed which is inside the loaddata variable.
}
@@ -27,12 +30,12 @@ class App extends Component {
self.setState({products:data})
// we are inside of a promise here and
// "then" here is screwing up our "this" hence a reference is created
- // before the promise is loaded. self is referring to the component
+ // before th e promise is loaded. self is referring to the component
// here. But if self is not used and this is placed along with the
// setState then this referes to the promise and no longer to the
// component because it is asynchronous.
- // everytime setState is called, it will render that component again and
- // all the components inside of it but not outside of it
+ // everytime setState is called, it will render that component and
+ // all the components inside of it but not outside of it again
},err => {
});
@@ -41,7 +44,8 @@ class App extends Component {
productList = () => {
const list = this.state.products.map((product) =>
+
+
+
{this.productList()}
+
+
+
+ {/* a row is taken first which contains two columns, products
+ and wishlist.Then within the products column productsList is inserted */}
+
+
+
@@ -65,4 +79,18 @@ class App extends Component {
}
export default App;
-
\ No newline at end of file
+// the complete description
+/* we load the data and when the data is loaded we set the state, refresh the Ui with data.
+when you see .then we can no longer use this unless we grab a reference to it
+such as self setstate Here. in this example products is refreshed
+which we get from the server goes into the products array and the render
+function is called again. this.productlist function is called which uses
+javascript mapping array .we prettymuch use map function whenever we have a list
+in react. map goes to every item in the list that we have in the
+products array in this state, frop that product into the "product" parameter
+and grab the element out of it, put it into our component, we pass the elements
+into different properties and then we return the list which is rendered
+ to the screen. Now in the product.js, we access the list by saying this.props.imgUrl
+ which is coming from the parent. when the setstate is called, product.js is also
+ rendered
+*/
\ No newline at end of file
diff --git a/src/product-condensed/product-condensed.css b/src/product-condensed/product-condensed.css
new file mode 100644
index 0000000..26fd5f7
--- /dev/null
+++ b/src/product-condensed/product-condensed.css
@@ -0,0 +1,3 @@
+.pc-condensed a{
+ margin-right:25px;
+}
\ No newline at end of file
diff --git a/src/product-condensed/product-condensed.js b/src/product-condensed/product-condensed.js
new file mode 100644
index 0000000..17ee923
--- /dev/null
+++ b/src/product-condensed/product-condensed.js
@@ -0,0 +1,15 @@
+import React, { Component } from 'react'//we are grabbing one specific thing 'component' from react,hence curly braces
+import './product-condensed.css';
+
+class ProductCondensed extends Component{
+ render(){
+ return (
+
+ X
+ {this.props.product.title} | ${this.props.product.price}
+
+ )
+ }
+}
+
+export default ProductCondensed;
\ No newline at end of file
diff --git a/src/product/product.css b/src/product/product.css
index 1b14fc1..6528dd8 100644
--- a/src/product/product.css
+++ b/src/product/product.css
@@ -1,7 +1,7 @@
.Product {
- width:20rem;
+ max-width:15rem;
}
.Product img {
- max-height:15rem;
+ max-height:10rem;
}
diff --git a/src/product/product.js b/src/product/product.js
index ea1bfb7..bfa16df 100644
--- a/src/product/product.js
+++ b/src/product/product.js
@@ -1,16 +1,34 @@
import React, { Component } from 'react'//we are grabbing one specific thing 'component' from react,hence curly braces
import './product.css';
+import DataService from '../services/data-service';
+
+let ds = new DataService();
class Product extends Component{
+
+ constructor(props){
+ super(props);
+ this.onButtonClicked = this.onButtonClicked.bind(this);
+ }
+ onButtonClicked = () =>{
+ ds.addWishListItem(this.props.product);
+// when we add whishlist item, then we enter the dataservice, it added the item,
+// and the notification is posted which is passing the brand new wishlist with
+// all the items. Now, since wishlist.js file is listening, it is going to pass
+// in as a newWishlist and then we set the state for the new items in the wishlist.
+
+ }
+
render(){
+
return (
-

+

{/* curly braces is a special syntax to insert javascript */}
diff --git a/src/services/data-service.js b/src/services/data-service.js
new file mode 100644
index 0000000..274229a
--- /dev/null
+++ b/src/services/data-service.js
@@ -0,0 +1,56 @@
+import NotificationService, {NOTIF_WISHLIST_CHANGED} from './notification-service';
+
+let ns = new NotificationService();
+// no matter how many times a new object of type notificationservice is created,
+// it will still reference to the same one in memory
+let instance = null;
+var wishList = [];
+
+class DataService{
+ constructor(){
+ if(!instance){
+ instance = this;
+ // if instance is created for the very first time, we are
+ // making it not null and create once in memory at "this" point in time
+ // and we store in the instance permanently
+ // now next time an object of the class is created, it checks that
+ // the object is not null and thus returns the same instance
+
+ }
+ return instance;
+ }
+ addWishListItem = item => {
+ wishList.push(item);
+ ns.postNotification(NOTIF_WISHLIST_CHANGED,wishList);
+ // posts notification with the new item in the wish list
+ }
+ removeWishListItem = item => {
+ for(var x=0; x
{
@@ -7,14 +7,14 @@ class HttpService {
// 2
fetch('http://localhost:3002/product')
.then(res => {
-// 4
+ //then is chained to whatever fetch is returning
+ // 4
resolve(res.json());
- //josn takes the response and converts to json
+ //json takes the response and converts to json
})
});
// 3
return promise;
- //then is chained to whatever fetch is returning
}
}
diff --git a/src/services/notification-service.js b/src/services/notification-service.js
new file mode 100644
index 0000000..ab03257
--- /dev/null
+++ b/src/services/notification-service.js
@@ -0,0 +1,66 @@
+// we could also make our http service a singleton which is not needed here.
+// If there is app that has multipe components and those components needs to access the
+// HTTP service we would want to make it a singleton.
+export const NOTIF_WISHLIST_CHANGED = "notif_wishlist_changed";
+// in our data-service, we need to start posting notifications, but before posting
+// notifications, we need to have a central place where we can store them
+var observers = {};
+let instance = null;
+class NotificationService {
+ constructor(){
+ if (!instance){
+ instance = this;
+ }
+
+ return instance;
+ }
+
+ postNotification = (notifName, data) => {
+ let obs = observers[notifName];
+ for (var x = 0; x < obs.length; x++){
+ var obj = obs[x];
+ obj.callBack(data);
+ }
+ }
+ removeObserver = (observer,notifName) => {
+ var obs = observers[notifName];
+ if(obs) {
+ for (var x=0; x {
+ let obs = observers[notifName];
+
+ if(!obs){
+ observers[notifName] = [];
+ //if there is no array in there,
+ // that means we have never registered for that notification
+ // before. So we are creating an
+ // empty array at tha slot for that specific notification
+ // name that is passed to this function
+ }
+ let obj = {observer: observer, callBack: callBack};
+ observers[notifName].push(obj);
+ // notification name is used as a special key on our observers list
+ // and pushed to that array
+ }
+}
+
+export default NotificationService;
+// we store a list of observers. An observer is a class or a component. An observer is a class or a component that says hello, I would like to listen
+// (kind of like register to vote, here class registers to observe) and when it is time to be notified. Obbserver will register and the system will send
+// back notifications when it is time to be notified.
\ No newline at end of file
diff --git a/src/wishlist/wishlist.css b/src/wishlist/wishlist.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/wishlist/wishlist.js b/src/wishlist/wishlist.js
new file mode 100644
index 0000000..9e41290
--- /dev/null
+++ b/src/wishlist/wishlist.js
@@ -0,0 +1,61 @@
+import React, { Component } from 'react'//we are grabbing one specific thing 'component' from react,hence curly braces
+import './wishlist.css';
+import ProductCondensed from '../product-condensed/product-condensed'
+import DataService from '../services/data-service';
+import NotificationService,{NOTIF_WISHLIST_CHANGED} from '../services/notification-service'
+
+let ns = new NotificationService();
+class WishList extends Component{
+
+ constructor(props){
+ super(props);
+
+ this.state = {wishList:[]};
+ // bind functions
+ this.createWishList = this.createWishList.bind(this);
+ this.onWishListChanged = this.onWishListChanged.bind(this);
+ }
+
+// when the component is mounting or it is about to load or if it did just load on
+// the screen we can do something, same goes with unmount, we can do something when
+// it goes out of memory
+ componentDidMount() {
+ ns.addObserver(NOTIF_WISHLIST_CHANGED, this, this.onWishListChanged)
+ // we can add ourselves an observer here
+ }
+
+ componentWillUnmount(){
+ ns.removeObserver(this, NOTIF_WISHLIST_CHANGED);
+ // we can remove ourelves an observer here. If we dont remove ourselves
+ // an observer here, we could have a memory leak on our app. The notification
+ // service will still hold on to this entire component even though it is not
+ // on the screen anymore.
+ }
+
+ onWishListChanged(newWishList){
+ this.setState({wishList: newWishList})
+ }
+
+ createWishList = () => {
+ const list = this.state.wishList.map((product) =>
+
+
+ )
+ return (list);
+ }
+
+ render(){
+ return (
+
+
+
wish List
+
+ {this.createWishList()}
+
+
+
+ );
+ }
+}
+
+export default WishList;
\ No newline at end of file