Skip to content

Commit

Permalink
Change to fetch method
Browse files Browse the repository at this point in the history
  • Loading branch information
iwanbazz committed Aug 27, 2020
1 parent d525b58 commit 536ecea
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 37 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ crate-type = ["cdylib","rlib"]
[dependencies]
yew = "0.17"
wasm-bindgen = "0.2"
anyhow = "1.0.32"
serde = { version = "1.0", features = ["derive"] }
16 changes: 16 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::types::Product;
use anyhow::Error;
use yew::callback::Callback;
use yew::format::{Json, Nothing};
use yew::services::fetch::{FetchService, FetchTask, Request, Response};

pub type FetchResponse<T> = Response<Json<Result<T, Error>>>;
type FetchCallback<T> = Callback<FetchResponse<T>>;

pub fn get_products(callback: FetchCallback<Vec<Product>>) -> FetchTask {
let req = Request::get("/products/products.json")
.body(Nothing)
.unwrap();

FetchService::fetch(req, callback).unwrap()
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod api;
mod types;
mod pages;

use pages::Home;
Expand Down
97 changes: 60 additions & 37 deletions src/pages/home.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,78 @@
use crate::api;
use crate::types::{CartProduct, Product};
use anyhow::Error;
use yew::format::Json;
use yew::services::fetch::FetchTask;
use yew::prelude::*;

#[derive(Clone)]
struct Product {
id: i32,
name: String,
description: String,
image: String,
price: f64,
}

struct CartProduct {
product: Product,
quantity: i32,
}

struct State {
products: Vec<Product>,
cart_products: Vec<CartProduct>,
get_product_error: Option<Error>,
get_products_loaded: bool,
}

pub struct Home {
state: State,
link: ComponentLink<Self>
link: ComponentLink<Self>,
task: Option<FetchTask>,
}

pub enum Msg {
AddToCart(i32)
AddToCart(i32),
GetProducts,
GetProductsSuccess(Vec<Product>),
GetProductsError(Error),
}

impl Component for Home {
type Message = Msg;
type Properties = ();

fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
let products: Vec<Product> = vec![
Product {
id: 1,
name: "Apple".to_string(),
description: "An apple a day keeps the doctor away".to_string(),
image: "/products/apple.png".to_string(),
price: 3.65,
},
Product {
id: 2,
name: "Banana".to_string(),
description: "An old banana leaf was once young and green".to_string(),
image: "/products/banana.png".to_string(),
price: 7.99,
},
];
let products = vec![];
let cart_products = vec![];

link.send_message(Msg::GetProducts);

Self {
state: State {
products,
cart_products,
get_product_error: None,
get_products_loaded: false,
},
link,
task: None,
}
}

fn update(&mut self, message: Self::Message) -> ShouldRender {
match message {
Msg::GetProducts => {
self.state.get_products_loaded = false;
let handler =
self.link
.callback(move |response: api::FetchResponse<Vec<Product>>| {
let (_, Json(data)) = response.into_parts();
match data {
Ok(products) => Msg::GetProductsSuccess(products),
Err(err) => Msg::GetProductsError(err),
}
});
self.task = Some(api::get_products(handler));
true
}
Msg::GetProductsSuccess(products) => {
self.state.products = products;
self.state.get_products_loaded = true;
true
}
Msg::GetProductsError(error) => {
self.state.get_product_error = Some(error);
self.state.get_products_loaded = true;
true
}
Msg::AddToCart(product_id) => {
let product = self
.state
Expand Down Expand Up @@ -116,11 +127,23 @@ impl Component for Home {
.iter()
.fold(0.0, |acc, cp| acc + (cp.quantity as f64 * cp.product.price));

html! {
<div>
<span>{format!("Cart Value: {:.2}", cart_value)}</span>
<span>{products}</span>
</div>
if !self.state.get_products_loaded {
html! {
<div>{"Loading ..."}</div>
}
} else if let Some(_) = self.state.get_product_error {
html! {
<div>
<span>{"Error loading products! :("}</span>
</div>
}
} else {
html! {
<div>
<span>{format!("Cart Value: {:.2}", cart_value)}</span>
<span>{products}</span>
</div>
}
}
}
}
16 changes: 16 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Product {
pub id: i32,
pub name: String,
pub description: String,
pub image: String,
pub price: f64,
}

#[derive(Clone, Debug)]
pub struct CartProduct {
pub product: Product,
pub quantity: i32,
}

0 comments on commit 536ecea

Please sign in to comment.