Reputation: 11
Im very new to making websites and Im trying to create a pokedex which is showing on a webseite and when searching for generation and type it will create a http response containing a json document which will then filter the pokemon and only show the corresponding ones. Im trying to use pokeapi to achieve this. Currently Im using xampp apache. I've been using some ChatGPT to help me start but im stuck at the backend.
<br/>
<b>Fatal error</b>
: Maximum execution time of 120 seconds exceeded in <b>\backend.php</b>
on line <b>19</b>
<br/>
[Error in DevTools](https://i.sstatic.net/5kMZg.png)
[backend.php not showing](https://i.sstatic.net/OWFb2.png)
[Here it is](https://i.sstatic.net/3KHte.png)
As Im very new to this Im not very skilled in debugging/troubleshooting but I can add the code I have Most of you will probably understand it better than me. I think you can ignore the comments as they are in german, but please tell me if you'd like to have them in english:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pokemon web app</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="/css/frontend.css">
</head>
<body class="w3-container">
<nav>
<ul>
<li><a href="#information">Information</a></li>
<li><a href="#input">Input</a></li>
<li><a href="#response">Response</a></li>
</ul>
</nav>
<section id="information">
<h2>Information</h2>
<p>You can find infos here</p>
</section>
<section id="input">
<h2>Input</h2>
<label for="generation">Generation:</label>
<select id="generation">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
<label for="firstType">First type:</label>
<select id="firstType">
<option value="normal">Normal</option>
<option value="fire">Fire</option>
<option value="water">Water</option>
<option value="electric">Electric</option>
<option value="grass">Grass</option>
<option value="ice">Ice</option>
<option value="fighting">Fighting</option>
<option value="poison">Poison</option>
<option value="ground">Ground</option>
<option value="flying">Flying</option>
<option value="psychic">Psychic</option>
<option value="bug">Bug</option>
<option value="rock">Rock</option>
<option value="ghost">Ghost</option>
<option value="dragon">Dragon</option>
<option value="dark">Dark</option>
<option value="steel">Steel</option>
<option value="fairy">Fairy</option>
</select>
<label for="secondType">Second type:</label>
<select id="secondType">
<option value="none">None</option>
<option value="normal">Normal</option>
<option value="fire">Fire</option>
<option value="water">Water</option>
<option value="electric">Electric</option>
<option value="grass">Grass</option>
<option value="ice">Ice</option>
<option value="fighting">Fighting</option>
<option value="poison">Poison</option>
<option value="ground">Ground</option>
<option value="flying">Flying</option>
<option value="psychic">Psychic</option>
<option value="bug">Bug</option>
<option value="rock">Rock</option>
<option value="ghost">Ghost</option>
<option value="dragon">Dragon</option>
<option value="dark">Dark</option>
<option value="steel">Steel</option>
<option value="fairy">Fairy</option>
</select>
<button onclick="sendData()">Start search</button>
</section>
<section id="response">
<h2>Response</h2>
<div id="output"></div>
<div class="container">
<h1>All Pokemon</h1>
<ul id="pokedex"></ul>
</div>
<button onclick="scrollToTop()" id="scrollToTopBtn" title="Back to top">▲</button>
<script src="/js/javascript.js"></script>
</section>
</body>
</html>
JavaScript
const pokedex = document.getElementById('pokedex');
const scrollToTopBtn = document.getElementById('scrollToTopBtn');
const outputDiv = document.getElementById('output');
const fetchPokemon = () => {
const promises = [];
for (let i = 1; i <= 1008; i++) {
const url = `https://pokeapi.co/api/v2/pokemon/${i}`;
promises.push(fetch(url).then((res) => res.json()));
}
Promise.all(promises).then((results) => {
const pokemon = results.map((result) => ({
name: result.name,
image: result.sprites['front_default'],
type: result.types.map((type) => type.type.name).join(', '),
id: result.id
}));
displayPokemon(pokemon);
});
};
const displayPokemon = (pokemon) => {
console.log(pokemon);
const pokemonHTMLString = pokemon
.map(
(pokeman) => `
<li class="card">
<img class="card-image" src="${pokeman.image}"/>
<h2 class="card-title">${pokeman.id}. ${pokeman.name}</h2>
<p class="card-subtitle">Type: ${pokeman.type}</p>
</li>
`
)
.join('');
pokedex.innerHTML = pokemonHTMLString;
};
fetchPokemon();
scrollToTopBtn.addEventListener('click', () => {
scrollToTop();
});
//Button um nach oben zu kommen beim runterscrollen
window.onscroll = function () {
updateScrollToTopBtnVisibility();
};
function updateScrollToTopBtnVisibility() {
// Zeige den Button nur, wenn der Benutzer nach unten gescrollt hat
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
scrollToTopBtn.style.display = 'block';
} else {
scrollToTopBtn.style.display = 'none';
}
}
function scrollToTop() {
// Scrollt die Seite nach oben, wenn der Button geklickt wird
document.body.scrollTop = 0; // Für ältere Browser
document.documentElement.scrollTop = 0; // Für moderne Browser
}
function sendData() {
const generation = document.getElementById('generation').value;
const firstType = document.getElementById('firstType').value;
const secondType = document.getElementById('secondType').value;
const data = {
generation: generation,
firstType: firstType,
secondType: secondType
};
fetch("../backend.php", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
// Hier kannst du die Antwort vom Backend weiter verarbeiten
console.log(data);
// Beispiel: Anzeigen der empfangenen Nachricht im Ausgabebereich
document.getElementById('output').innerHTML = data.message;
})
.catch((error) => {
console.error('Error:', error);
});
}
CSS
body {
background-color: orangered;
color: white;
margin: 0;
font-family: rubik;
}
.container {
padding: 40px;
margin: 0 auto;
}
h1 {
text-transform: uppercase;
text-align: center;
font-size: 54px;
}
#pokedex {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
grid-gap: 20px;
padding-inline-start: 0;
}
.card {
list-style: none;
padding: 40px;
background-color: #f4f4f4;
color: #222;
text-align: center;
}
.card:hover {
animation: bounce 0.5s linear;
}
.card-title {
text-transform: capitalize;
margin-bottom: 0px;
font-size: 32px;
font-weight: normal;
}
.card-subtitle {
margin-top: 5px;
color: #666;
font-weight: lighter;
}
.card-image {
height: 180px;
}
@keyframes bounce {
20% {
transform: translateY(-6px);
}
40% {
transform: translateY(0px);
}
80% {
transform: translateY(-2px);
}
100% {
transform: translateY(0);
}
}
#scrollToTopBtn {
display: none;
position: fixed;
bottom: 20px;
right: 20px;
font-size: 20px;
border: none;
background-color: #007BFF;
color: white;
cursor: pointer;
padding: 10px;
border-radius: 5px;
}
#scrollToTopBtn:hover {
background-color: #0056b3;
}
/* Zeige den Button nur, wenn der Benutzer nach unten gescrollt hat */
body::-webkit-scrollbar {
width: 12px;
}
body::-webkit-scrollbar-thumb {
background-color: #007BFF;
}
body::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
body.scrolled-up #scrollToTopBtn {
display: none;
}
body.scrolled-down #scrollToTopBtn {
display: block;
}
and the backend
<?php
// Überprüfen, ob die Anfrage die erwarteten Daten enthält
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$generation = isset($_POST['generation']) ? $_POST['generation'] : null;
$firstType = isset($_POST['firstType']) ? $_POST['firstType'] : null;
$secondType = isset($_POST['secondType']) ? $_POST['secondType'] : null;
// Beispiel: Pokemon-Daten von der PokeAPI abrufen
$url = "https://pokeapi.co/api/v2/pokemon?limit=1000";
$pokemonData = file_get_contents($url);
$pokemonData = json_decode($pokemonData, true);
// Filtere Pokemon basierend auf den ausgewählten Typen
$filteredPokemon = [];
foreach ($pokemonData['results'] as $pokemon) {
$pokemonDetails = file_get_contents($pokemon['url']);
$pokemonDetails = json_decode($pokemonDetails, true);
// Überprüfe, ob das Pokemon den ausgewählten Typen entspricht
$hasFirstType = false;
$hasSecondType = false;
foreach ($pokemonDetails['types'] as $type) {
if ($type['type']['name'] === $firstType) {
$hasFirstType = true;
}
if ($type['type']['name'] === $secondType) {
$hasSecondType = true;
}
}
// Füge Pokemon zur Ergebnisliste hinzu, wenn es den ausgewählten Typen entspricht
if ($hasFirstType && $hasSecondType) {
$filteredPokemon[] = [
'name' => $pokemonDetails['name'],
'image' => $pokemonDetails['sprites']['front_default'],
'type' => implode(', ', array_column($pokemonDetails['types'], 'type.name')),
'id' => $pokemonDetails['id']
];
}
}
// Beispiel: Hier wird einfach eine JSON-Antwort mit den empfangenen Daten zurückgegeben
$response = [
'generation' => $generation,
'firstType' => $firstType,
'secondType' => $secondType,
'filteredPokemon' => $filteredPokemon,
'message' => 'Daten erfolgreich empfangen und verarbeitet!'
];
// Setzen eines Cookies (Hier wird ein einfaches Timestamp-Cookie gesetzt)
setcookie('custom_cookie', time(), time() + 3600, '/'); // Gültig für 1 Stunde
// Senden der JSON-Antwort
header('Content-Type: application/json');
echo json_encode($response);
} else {
// Falls die Anfrage nicht korrekt ist, eine Fehlermeldung senden
header('HTTP/1.1 400 Bad Request');
echo json_encode(['error' => 'Ungültige Anfrage']);
}
?>
I'd greatly appreciate all help.
Upvotes: 1
Views: 53