Skip to content
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
37 changes: 37 additions & 0 deletions index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

body {
font-family: sans-serif;
}

main {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
grid-template-areas:
"list details"
"list reserve"
}

#trips-list {
grid-area: list;
}

#trip-details {
grid-area: details;
}

#reserve-trip {
grid-area: reserve;
}

#status-message {

}

#trips-button {

}

#reservation-form {

}
46 changes: 46 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Pets with axios</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript" src="index.js"></script>
<link rel="stylesheet" href="index.css">
</head>
<body>

<main>
<section id="status-message"></section>

<section>
<h1>Trek</h1>
<button id="trips-button">See All Trips</button>
<ul id="trips-list"></ul>
</section>

<section>
<h1>Trip Details</h1>
<ul id="trip-details"></ul>
</section>

<section id="reserve-trip">
<h1>Reserve a Spot on Example Trip</h1>
<form id="reservation-form">
<div>
<label for="name">Name</label>
<input type="text" name="name" />
</div>

<div>
<label for="email">Email</label>
<input type="text" name="email" />
</div>

<input type="submit" value="Reserve" />
</form>
</section>
</main>
</body>
</html>

125 changes: 125 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const URL = 'https://trektravel.herokuapp.com/trips/'

// Status Management
const reportStatus = (message) => {
$('#status-message').html(message);
};

const reportError = (message, errors) => {
let content = `<p>${message}</p><ul>`;
for (const field in errors) {
for (const problem of errors[field]) {
content += `<li>${field}: ${problem}</li>`;
}
}
content += "</ul>";
reportStatus(content);
};

// Wave 1 - Display
const displayTripsList = (tripsList) => {
const target = $('#trips-list');
target.empty();
tripsList.forEach(trip => {
target.append(`<li id="${trip.id}">${trip.name}</a></li>`);

const tripID = $(`#${trip.id}`);
tripID.click(() => loadTripDetails(trip));
});
}

// Wave 1 - Load
const loadTrips = () => {
reportStatus("loading trips...");

axios.get(URL)
.then((response) => {
const trips = response.data;
displayTripsList(trips);
reportStatus(`Successfully loaded ${trips.length} trips`);
})
.catch((error) => {
reportStatus(`Encountered an error while loading trips: ${error.message}`);
console.log(error);
});
}

// Wave 2 - Display
const displayTripDetails = (trip) => {
const target = $('#trip-details');
target.empty();

target.append(`<h1>Trip Details</h1>`);
target.append(`<li>ID: ${trip.id}</li>`);
target.append(`<li>Name: ${trip.name}</li>`);
target.append(`<li>Continent: ${trip.continent}</li>`);
target.append(`<li>Category: ${trip.category}</li>`);
target.append(`<li>Weeks: ${trip.weeks}</li>`);
target.append(`<li>Cost: $${trip.cost.toFixed(2)}</li>`);
target.append(`<li>About: ${trip.about}</li>`);
}

// Wave 2 - Load
const loadTripDetails = (trip) => {
reportStatus(`loading details for trip ${trip.name}`);

axios.get(URL + trip.id)
.then((response) => {
const trip = response.data;
displayTripDetails(trip);

reportStatus(`Successfully loaded details for: ${trip.name}`);
$('#reservation-form').submit(() => reserveTrip(trip))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So every time I click on a trip you add another event handler which will run when the form gets submitted. You should use $('#reservation-form').off() to clear out any existing event handlers first.

Oh and nice closure!

})
.catch((error) => {
reportStatus(`Encountered an error while loading trip: ${error.message}`);
console.log(error);
});
}

// Wave 3
const readFormData = () => {
const parsedFormData = {};

// const fields = ['name', 'email'];
// for (let field in fields) {
// const dataFromForm = $(`#reservation-form input[name=${field}]`).val();
// parsedFormData[field] = dataFromForm ? dataFromForm : undefined;
// }
parsedFormData.name = $("input[name='name']").val();
parsedFormData.email = $("input[name='email']").val();
return parsedFormData;
}

const clearForm = () => {
$(`#pet-form input[name="name"]`).val('');
$(`#pet-form input[name="email"]`).val('');
}

const reserveTrip = (trip) => {
event.preventDefault();
const reservationData = readFormData();

reportStatus(`Sending reservation data for: ${trip.name}`);

axios.post(URL + trip.id + '/reservations', reservationData)
.then((response) => {
reportStatus(`Successfully added a reservation with ID ${response.data.id}!`);
clearForm();
})
.catch((error) => {
console.log(error.response);
if (error.response.data && error.response.data.errors) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should include: if (error.response && error.response.data && error.response.data.errors) {

just so that if there's a network error the error can be reported. (no response object for a network error).

reportError(
`Encountered an error: ${error.message}`,
error.response.data.errors
);
} else {
reportStatus(`Encountered an error: ${error.message}`);
}
});
}

$(document).ready(() => {
$('#trips-button').on('click', loadTrips);
});