How to make my code dry in JavaScript during API Call - javascript

SO I am calling 5 APIs in my js file and the code is the same for all except the URL and the form data I am passing. and same lines of code repeats 5 times and I think this is not the good of writing. What I want is to make this code dry but don't know what changes I should make
var formdata = new FormData();
formdata.append("market", "KSE100");
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch(
"api_url here_1",
requestOptions
)
.then((response) => response.json())
.then((stockData) => console.log('aasfs',stockData ))
.catch((error) => console.log("error", error));
var formdata = new FormData();
formdata.append("symbol", "SYS");
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch(
"api_url here_2",
requestOptions
)
.then((response) => response.json())
.then((stockData) => console.log('aasfs',stockData ))
.catch((error) => console.log("error", error));

Wrap the common code in a function passing in the form data and url via variables
const sendFormData = (url, formData) => {
var requestOptions = {
method: "POST",
body: formData,
redirect: "follow",
};
fetch(
url,
requestOptions
)
.then((response) => response.json())
.then((stockData) => console.log('aasfs', stockData))
.catch((error) => console.log("error", error));
}
var formdata1 = new FormData();
formdata.append("market", "KSE100");
sendFormData("api_url here_1", formdata1);
var formdata2 = new FormData();
formdata.append("symbol", "SYS");
sendFormData("api_url here_2", formdata2);

You can define a function like this
const postData = (url, data) => {
const formdata = new FormData();
Object.entries(data).forEach(([k, v]) => {
formdata.append(k, v);
}
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
return fetch(
url,
requestOptions
)
.then((response) => response.json())
.then((stockData) => console.log('aasfs',stockData ))
.catch((error) => console.log("error", error));
}

Related

Why am I getting an error running this code? JSON DOM manipulation

Trying to populate a website given a local json file. How can I go about getting the information on the json to show up on the html website? I don't see any changes on the html and inspect on shows an error that id is not defined.
const baseUrl = 'http://localhost:3000/films';
let film = [];
document.addEventListener('DOMContentLoaded', () => {
const getFirstFilm = () => {
fetch(baseUrl + id)
.then(response => response.json())
.then(data => "{renderFirstFilm(data)}")
}
getFirstFilm();
})
const renderFirstFilm = (film) => {
const poster = document.getElementById('poster')
poster.src = film.poster
}
renderFirstFilm();
fetch('http://localhost:3000/films', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
})

Uncaught (in promise) TypeError: res.map is not a function

I'm trying to fetch a list of departments from an url in a react native application
import React,{ useState,useEffect} from 'react';
import { StyleSheet, LogBox,View,Text } from 'react-native';
export default function App() {
var [department,setDepartment]=useState([])
const token = /* my token here */
const getDepartments=()=>{
const url = /*my api's url here*/
return fetch(url, {
method: 'GET',
headers: { "Authorization": "Bearer" + token ,
'Accept': 'application/json',
'Content-Type':'application/json'
}
})
.then(response => response.json())
.then(data=>console.log(data)) // returns the correct data
.catch(error => console.error(error))
}
const getdepartment = async () => {
await getDepartments().then((res) => //here lays the problem
{res.map((p, key) => {
department.push({
name: p.name,
id: p.id,
});
});
});
};
useEffect(() => {
getdepartment();
}, []);
return (
<View>
<Text>
{department[0]}
</Text>
</View>
)
}
here res in the getdepartment() function is undefined despite the getDepartments() function returning correct data from the url
You are not returning a value from getDepartments, just a simple console.log.
You can convert the function in async/await:
const getDepartments = async () => {
const url = /*my api's url here*/
try {
const response = await fetch(url, {
method: 'GET',
headers: { "Authorization": "Bearer" + token ,
'Accept': 'application/json',
'Content-Type':'application/json'
}
})
return await response.json();
} catch(e){
// error
}
}
or return a value from your function:
const getDepartments=()=>{
const url = /*my api's url here*/
return fetch(url, {
method: 'GET',
headers: { "Authorization": "Bearer" + token ,
'Accept': 'application/json',
'Content-Type':'application/json'
}
})
.then(response => response.json())
.catch(error => console.error(error))
}
If you are returning the result of the fetch then just return the result obtained from it, the issue is along with fetch, the response is also handled and the complete thing post to that is being returned which is not the result so you just need to skip this line .then(data=>console.log(data))
const getDepartments=()=>{
const url = /*my api's url here*/
return fetch(url, {
method: 'GET',
headers: { "Authorization": "Bearer" + token ,
'Accept': 'application/json',
'Content-Type':'application/json'
}
}).then(response => response.json()).catch(error =>
console.error(error))
}
// Here after fetching the result you can map the data
const getdepartment = async () => {
await getDepartments().then((res) =>
{res.map((p, key) => {
department.push({
name: p.name,
id: p.id,
});
});
});
};

Why i got the output as "\"userName\"" and not like that "userName"?

Why i got output "\"userName\"" and not as "userName" ?
in my example i try to do an get api that attach to it some data and that data comes from the async-storage.
when i console the output so its shows the data like that :
"\"userName\""
but it should output "userName" .
what is the way to fix that issue ?
so what is wrong in my way ?
const getSaveUserTokenData = async (data) => {
const url =
'https://URL/userName,userToken,PlatformType,DeviceID?' +
'userName=' +
data.userName +
'&userToken=' +
data.googlToken +
'&PlatformType=' +
data.platformId +
'&DeviceID=' +
data.deviceId;
await fetch(
url,
{
method: 'GET',
headers: {
Authorization: data.azureToken,
},
}
)
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
};
You can write this way as well:
fetchFunction = async () => {
let data = {
userName: 'jon',
userToken: 'bee22',
PlatformType: 'os-ios',
DeviceID: '222222'
}
const url = `https://yoururl.com/?userName=${encodeURIComponent(data.userName)}&userToken=${encodeURIComponent(data.userToken)}&PlatformType=${encodeURIComponent(data.PlatformType)}&DeviceID=${encodeURIComponent(data.DeviceID)}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
const json = await response.json();
console.log(json);
}
If your variable names are the one you want in your url, try this:
const getData = async () => {
let userName = 'jon';
let userToken = 'bee22';
let PlatformType = 'os-ios';
let DeviceID = '222222';
const queryString = Object.entries({
userName,
userToken,
PlatformType,
DeviceID,
})
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
const response = await fetch(
'https://url...?' + queryString
);
};
};
Note: user token should not be in the url but usually in the headers of your request, like so:
fetch(someUrl, {
headers: {
Authorization: userToken
}
});
fetch(`https://yoururl.com/${userName}`,
{ method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default'
})
.then(function(response) {
//your code here
});
A more generic solution would be something like this:
async function get(route, ...params) {
const url = `${route}${params.map(p => `/${p}`)}`;
const response = await fetch(url, { method: "GET", headers });
if (!response.ok)
throw new Error(`Http error status: ${response.status}`);
return response.json();
}
by using ...params you can pass a generic amount of parameters that will then be combined with:
const url = `${route}${params.map(p => `/${p}`)}`;
In your case you would call the method like this:
const result = await get("https://url..", "jon", "bee22", "os-ios", "222222");

React Redux promise error - (...).then is not a function

Had a look for this in the questions that offered but this was the closest and it didnt really address my problem.
I have a code block (detailed a little way down the page) as part of a larger fetch block.. it gets to this codeblock and also runs fine if this code block is commented out i.e it carrys out a successful fetch etc and returns a JWT no problem but... add this block in and i get the following error:
TypeError: (0 , _localStorageDropDowns.confirmSelectDataExistance)(...).then is not a function
It is referring to this function in another folder (imported correctly)..
export const confirmSelectDataExistance = () => {
const companyStateShortNameJson = localStorage.getItem(COMPANYSTATESHORTNAME)
const statesJson = localStorage.getItem(STATES)
const suburbLocationsJson = localStorage.getItem(LOCATIONS)
if (companyStateShortNameJson || statesJson || suburbLocationsJson) {
console.log('something exists in localstorage')
return true
}
console.log('nothing in localstorage')
return false
}
simple function - returns true or false.
and here is the code block -its failing on the first line:
return confirmSelectDataExistance().then(isConfirmed => {
if (!isConfirmed) {
dispatch({ type: REQUEST_SELECT_DATA })
console.log('gets here!', isConfirmed)
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
});
return saveSelectData(selectData);
}
})
From my limited experience the "confirmSelectDataExistance" is a function so why is it saying that its not?
Finally here is the whole action in its entirety so you can see how it that block is called.. as I said - comment the block out and it works perfectly..
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
return confirmSelectDataExistance().then(isConfirmed => {
if (!isConfirmed) {
dispatch({ type: REQUEST_SELECT_DATA })
console.log('gets here!', isConfirmed)
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
});
return saveSelectData(selectData);
}
})
})
.catch(error => {
clearJwt()
console.log('ERROR - LOGIN!',error)
})
addTask(task)
return task
}
EDIT
I have finally got this to work after hacking away for hours.. Here is the finished action:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
// Now check local storage for dropdown data..
if (!confirmSelectDataExistance()) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = JSON.stringify(data)
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
});
}
})
.catch(error => {
clearJwt()
console.log('ERROR - LOGIN!', error)
})
addTask(task)
return task
}
and here is the function it calls:
export const confirmSelectDataExistance = () => {
const companyStateShortNameJson = localStorage.getItem(COMPANYSTATESHORTNAME)
const statesJson = localStorage.getItem(STATES)
const suburbLocationsJson = localStorage.getItem(LOCATIONS)
if (companyStateShortNameJson || statesJson || suburbLocationsJson) {
console.log('something exists in localstorage')
return true
}
console.log('nothing in localstorage')
return false
}
The one thing I changed from the other attempts is that I used "data" instead of calling "getJwt()". I then used the line:
const token = JSON.stringify(data)
to obtain the JWT I just got.
In the end I used #Karin s answer and ran with that. (upvoted by me)
The error is not saying that confirmSelectDataExistance is not a function, it's saying that then isn't a function on what is returned from it, which is a boolean (it would be equivalent to false.then(...), which doesn't work).
If seems like you're trying to use then as a conditional. In that case a simple if statement should work:
if (confirmSelectDataExistance()) {
// do things if it returns true
} else {
// do things if it returns false
}
export const confirmSelectDataExistance = () => {
return new Promise(function (resolve, reject) {
const companyStateShortNameJson = localStorage.getItem(COMPANYSTATESHORTNAME)
const statesJson = localStorage.getItem(STATES)
const suburbLocationsJson = localStorage.getItem(LOCATIONS)
if (companyStateShortNameJson || statesJson || suburbLocationsJson) {
console.log('something exists in localstorage')
resolve(true)
}
console.log('nothing in localstorage')
reject(false)
})
}
Try something like this:
export const confirmSelectDataExistance = new Promise((resolve, reject) => {
const companyStateShortNameJson = localStorage.getItem(COMPANYSTATESHORTNAME);
const statesJson = localStorage.getItem(STATES);
const suburbLocationsJson = localStorage.getItem(LOCATIONS);
if (companyStateShortNameJson || statesJson || suburbLocationsJson) {
console.log('something exists in localstorage');
resolve(true);
}
console.log('nothing in localstorage');
reject(false); // or resolve(false) if you want handle this situation inside then block also
});

Javascript: Fetch DELETE and PUT requests

I have gotten outside of GET and POST methods with Fetch. But I couldn't find any good DELETE and PUT example.
So, I ask you for it. Could you give a good example of DELETE and PUT methods with fetch. And explain it a little bit.
Here is a fetch POST example. You can do the same for DELETE.
function createNewProfile(profile) {
const formData = new FormData();
formData.append('first_name', profile.firstName);
formData.append('last_name', profile.lastName);
formData.append('email', profile.email);
return fetch('http://example.com/api/v1/registration', {
method: 'POST',
body: formData
}).then(response => response.json())
}
createNewProfile(profile)
.then((json) => {
// handle success
})
.catch(error => error);
Ok, here is a fetch DELETE example too:
fetch('https://example.com/delete-item/' + id, {
method: 'DELETE',
})
.then(res => res.text()) // or res.json()
.then(res => console.log(res))
For put method we have:
const putMethod = {
method: 'PUT', // Method itself
headers: {
'Content-type': 'application/json; charset=UTF-8' // Indicates the content
},
body: JSON.stringify(someData) // We send data in JSON format
}
// make the HTTP put request using fetch api
fetch(url, putMethod)
.then(response => response.json())
.then(data => console.log(data)) // Manipulate the data retrieved back, if we want to do something with it
.catch(err => console.log(err)) // Do something with the error
Example for someData, we can have some input fields or whatever you need:
const someData = {
title: document.querySelector(TitleInput).value,
body: document.querySelector(BodyInput).value
}
And in our data base will have this in json format:
{
"posts": [
"id": 1,
"title": "Some Title", // what we typed in the title input field
"body": "Some Body", // what we typed in the body input field
]
}
For delete method we have:
const deleteMethod = {
method: 'DELETE', // Method itself
headers: {
'Content-type': 'application/json; charset=UTF-8' // Indicates the content
},
// No need to have body, because we don't send nothing to the server.
}
// Make the HTTP Delete call using fetch api
fetch(url, deleteMethod)
.then(response => response.json())
.then(data => console.log(data)) // Manipulate the data retrieved back, if we want to do something with it
.catch(err => console.log(err)) // Do something with the error
In the url we need to type the id of the of deletion: https://www.someapi/id
Just Simple Answer.
FETCH DELETE
function deleteData(item, url) {
return fetch(url + '/' + item, {
method: 'delete'
})
.then(response => response.json());
}
Here is good example of the CRUD operation using fetch API:
“A practical ES6 guide on how to perform HTTP requests using the Fetch API” by Dler Ari https://link.medium.com/4ZvwCordCW
Here is the sample code I tried for PATCH or PUT
function update(id, data){
fetch(apiUrl + "/" + id, {
method: 'PATCH',
body: JSON.stringify({
data
})
}).then((response) => {
response.json().then((response) => {
console.log(response);
})
}).catch(err => {
console.error(err)
})
For DELETE:
function remove(id){
fetch(apiUrl + "/" + id, {
method: 'DELETE'
}).then(() => {
console.log('removed');
}).catch(err => {
console.error(err)
});
For more info visit Using Fetch - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch > Fetch_API.
Some examples:
async function loadItems() {
try {
let response = await fetch(`https://url/${AppID}`);
let result = await response.json();
return result;
} catch (err) {
}
}
async function addItem(item) {
try {
let response = await fetch("https://url", {
method: "POST",
body: JSON.stringify({
AppId: appId,
Key: item,
Value: item,
someBoolean: false,
}),
headers: {
"Content-Type": "application/json",
},
});
let result = await response.json();
return result;
} catch (err) {
}
}
async function removeItem(id) {
try {
let response = await fetch(`https://url/${id}`, {
method: "DELETE",
});
} catch (err) {
}
}
async function updateItem(item) {
try {
let response = await fetch(`https://url/${item.id}`, {
method: "PUT",
body: JSON.stringify(todo),
headers: {
"Content-Type": "application/json",
},
});
} catch (err) {
}
}
Let me simplify this, you can straight up copy the code.
This is for PUT method :
fetch('https://reqres.in/api/users', + id {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'user'
})
})
.then(res => {
return res.json()
})
.then(data => console.log(data))
and this is for DELETE :
fetch('https://reqres.in/api/users' + id, {
method: 'DELETE',
})
.then(res => {
return res.json()
})
.then(data => console.log(data))
Note: I'm using dummy api here.
This is what worked for me when using the PUT method. This method allows me to effectively update the 1st item using my first name:
fetch('https://reqres.in/api/users', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: 1,
first_name: 'Anthony'
})
})
.then(res => {
return res.json()
})
.then(data => console.log(data))
Here are examples for Delete and Put for React & redux & ReduxThunk with Firebase:
Update (PUT):
export const updateProduct = (id, title, description, imageUrl) => {
await fetch(`https://FirebaseProjectName.firebaseio.com/products/${id}.json`, {
method: "PATCH",
header: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
description,
imageUrl,
}),
});
dispatch({
type: "UPDATE_PRODUCT",
pid: id,
productData: {
title,
description,
imageUrl,
},
});
};
};
Delete:
export const deleteProduct = (ProductId) => {
return async (dispatch) => {
await fetch(
`https://FirebaseProjectName.firebaseio.com/products/${ProductId}.json`,
{
method: "DELETE",
}
);
dispatch({
type: "DELETE_PRODUCT",
pid: ProductId,
});
};
};
const DeleteBtn = (id) => {
fetch(`http://localhost:8000/blogs/${id}`, {
method: "DELETE"
})
.then(() => {
navigate('/');
});
}
<button onClick={(event) => { DeleteBtn(blog.id)} }>delete</button>

Categories