localStorage.setItem("task", JSON.stringify(taskList));
getTaskList = JSON.parse(localStorage.getItem("task")) || [];
// Create an array and fill it. {length: 15} is an array-like object
Array.from({ length: 15 }, (_, i) => i)
// → [0, 1, 2, ..., 14]
function kochen() {
const kochMeldet = Match.random() > 0.5;
return new Promise((resolve, reject) => {
console.log("kochen");
if (kochMeldet === true) {
resolve("zubereitetes Gericht");
} else {
reject("Gericht nicht zubereitet");
}
});
}
kochen()
.then((gericht) => {
console.log("servieren", gericht);
})
.catch(() => {
console.log("nicht servieren");
})
.finally(() => {
console.log("der Koch hat gesprochen");
});
Promise.all() takes an array of promises and returns a new promise that resolves when all of the promises in the array have resolved.
If any of the promises in the array reject, the promise returned by Promise.all() will also reject.
async function fetchData() {
try {
const [response1, response2, response3] = await Promise.all([
fetch('https://api1.com/data'),
fetch('https://api2.com/data'),
fetch('https://api3.com/data'),
]);
if ([response1, response2, response3].every((response) => response.ok)) {
const [data1, data2, data3] = await Promise.all([
response1.json(),
response2.json(),
response3.json(),
]);
console.log(data1, data2, data3); // Data from all successful responses
} else {
throw new Error('Not all responses were successful');
}
} catch (error) {
console.error('Error:', error);
}
}
fetchData();
Gets a readable stream before using response.json()
Without a method it defaults to a get request
Fetch with nested then
fetch("https://swapi.de/api/people/8").then((response) => {
if (response.status === 200) {
response.json().then((result) => {
console.log(result);
});
} else {
throw new Error("Kein Character gefunden");
}
});
Fetch with chained then
fetch("https://swapi.de/api/people/8")
.then((response) => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("Kein Character gefunden");
}
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
Fetch with async await
const getCharacter = async () => {
try {
const response = await fetch("https://swapi.de/api/people/8");
if (response.status === 200) {
const result = await response.json();
} else {
throw new Error("Kein Character gefunden");
}
} catch (error) {
console.log(error);
}
};
export const loginApi = async (data) => {
try {
const response = await fetch("http://localhost:5000/api/user/login", {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
credentials: "include",
});
const userData = await response.json();
if (response.status === 200) {
console.log("Anmeldung erfolgreich!");
return userData;
}
throw new Error("Anmeldung fehlgeschlagen!");
} catch (error) {
console.log(error);
}
};
Advantage of axios: no converting to json needed
npm install axios
GET request with axios and then
import axios from "axios";
const getData = () => {
axios
.get(url)
.then((response) => console.log(response))
.catch((error) => console.log(error));
};
POST request with axios and async/await
import axios from "axios";
const handleSubmit = async () => {
try {
const response = await axios.post(url, userData, { withCredentials: true });
console.log(response);
} catch (error) {
console.log(error);
}
};
Using fetch with the URL constructor
const str = "http://127.0.0.1:5500/local-file.json?attempt=1&other=hi";
const url = new URL(str);
console.log(url.host, url.origin, url.protocol, url.port, url.pathname, url.seachParams);
// Add a search parameter
const sp = url.seachParams;
sp.append("api-key", "34093oijgreio3u091irwkrß9wie");
fetch(url);
Using fetch with string or URL or Request or Headers constructor
const str = "http://127.0.0.1:5500/local-file.json?attempt=1&other=hi";
const url = new URL(str);
const headers = new Headers();
headers.append("content-type", "application/json");
// Custom header name has to start with an "x"
headers.append("x-api-key", "2ß3u4usjfjofjoidsjgiodj");
const request = new Request(url, {
headers,
method: "GET",
cache: "no-cache",
credentials: "include"
});
// Either
fetch(str)
// or
fetch(url)
// or
fetch(request)
Options for cache/credentials
cache options:
- default: cache first, server request if stale, update cache if newer
- reload: always go to the server and update the cache
- no-store: always go to the server but do not update the cache
- no-cache: make a conditional request to the server and compare, update cache and use latest
- force-cache: only makes request if there is no HTTP cache file
- only-if-cache: from cache or 504 gateway timeout error
credentials options:
- omit: never send credentials
- same-origin: only send credentials for same-origin requests (default)
- include: always include credentials, even for cross-origin requests
Simulate or mock a response without making an actual network request
let obj = {
id: crypto.randomUUID(),
name: "John"
};
const jsonstring = JSON.stringify(obj);
const file = new File([jsonstring], "mydata.json", {type: "application/json"});
const respone = new Response(file, {
status: 200,
statusText: "Say my name",
headers: {
"content-type": "application/json",
"content-length": file.size, // file size in bytes
"x-name": "custom header name"
}
});
console.log(response);
// Access response header
console.log(response.headers.get("content-type"));
console.log(response.headers.get("content-length"));
fetch(imgstr)
.then(response => {
if (!response.ok) throw new Error("Invalid request");
return response.blob(); // binary large object (images, video, audio, fonts)
})
.then(blob => {
const url = new URL.createObjectURL(blob); // url that points to a spot in memory where the image data is stored
const img = document.querySelector("img");
img.src = url;
// Cleaning up memory when image is no longer needed
URL.revokeObjectURL(url);
})
.catch(error => {
console.log(error);
});
fetch(htmlfile)
.then(response => {
if (!response.ok) throw new Error("Invalid request");
return response.text();
})
.then(text => {
console.log(text);
})
.catch(error => {
console.log(error);
});
const url = "http://picsum.photos/id/237/3000/2000";
const controller = new AbortController();
const signal = controller.signal;
// Abort request on button click
const abortButton = document.querySelector("button");
abortButton.addEventListener("click", event => {
controller.abort();
console.log("Request aborted");
});
let request = new Request(url, {
signal
});
fetch(request)
.then(response => {
if (!response.ok) throw new Error("Invalid request");
return response.blob();
})
.then(blob => {
console.log("Blob received");
})
.catch(error => {
console.log(error);
});
An added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src https://*; child-src 'none';" />
Or set in the headers of a request:
headers: {
"Content-Security-Policy": "default-src 'self' example.com *.example.com";
}
const imgInput = document.querySelector("imgfile");
const endpoint = "http://127.0.0.1:5000";
// FormData can also be used if we don't have a form element in our HTML
const fd = new FormData();
// Custom name (accessible on the server, e.g. req.files.imageFile), the actual image file data, name of the uploaded file
fd.append("imageFile", imgInput.files[0], imgInput.files[0].name);
// Or passing the form to FormData. Each input needs to have the name attribute
const myForm = document.querySelector("#myForm");
const fd = new FormData(myForm);
const request = new Request(endpoint, {
method: "POST",
body: fd,
// No need to set headers; the browser handles the Content-Type header for multipart/form-data
});
fetch(request);
// Convert to object (optional)
const data = Object.fromEntries(fdk.entries());
console.log(data); // { username: "John", password: "1234" }
form.addEventListener('submit', function (e) {
e.preventDefault();
const username = form.elements['username'].value;
const password = form.elements['password'].value;
console.log({ username, password });
});
All requests apart from GET and HEAD need to include an origin header.
let imgBlob;
// As a sequence (one fetch and then the other)
fetch(imgstr)
.then(response => {
if (!response.ok) throw new Error("Invalid image request");
return response.blob();
})
.then(blob => {
imgBlob = blob; // Store the blob for later use
// Do something with blob if needed
return fetch(jsonstr);
})
.then(response => {
if (!response.ok) throw new Error("Invalid JSON request");
return response.json(); // Return the promise from response.json()
})
.then(jsonData => {
return Promise.all([imgBlob, jsonData]); // Use imgBlob instead of imgResponse
})
.then(([blob, jsonData]) => {
console.log(jsonData);
console.log(blob);
})
.catch(error => {
console.log(error);
});
// Both fetch at the same time
Promise.all([fetch(imgstr), fetch(jsonstr)])
.then(([imgResponse, jsonResponse]) => {
return Promise.all([imgResponse.blob(), jsonResponse.json()]);
})
.then(([blob, jsonData]) => {
console.log(blob);
console.log(jsonData);
})
.catch(error => {
console.log(error);
});
const io = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
const img = entry.target;
// const src=img.getAttribute("data-src");
console.log(entry.target.classList);
// img.setAttribute("src",src);
if (entry.target.classList.contains("dce_fade")) {
console.log("true");
img.classList.remove("dce__fade");
} else if (entry.target.classList.contains("from-left")) {
elem.classList.add("appear");
}
io.unobserve(entry.target);
// observer.disconnect();
});
},
{ threshold: 1, rootMargin: "0px 0px -100px 0px" }
);
// io.observe(target);
targets.forEach((target) => {
io.observe(target);
});
targets2.forEach((target) => {
io.observe(target);
});