How to pass query parameters to a url inside a lambda function (netlify environment) - reactjs

When the user submit a search form I want to add the query parameter to the api url that is inside a lambda function.
I set up the netlify environment inside a react app and initialize a lambda function.Now I only get the response using hard-coded queries.
How can I pass parameters to the event.queryStringParameters?
exports.handler = function(event, context, callback) {
const API_PARAMS = qs.stringify(event.queryStringParameters);
const { API_TOKEN, API_URL } = process.env;
const URL = `${API_URL}search?part=snippet&maxResults=5&key=${API_TOKEN}&q=animals`;
// Let's log some stuff we already have.
console.log("Injecting token to", API_URL);
console.log("logging event.....", event);
console.log("Constructed URL is ...", URL);
console.log('params are...', API_PARAMS);
const pass = body => {
callback(null, {
statusCode: 200,
body: JSON.stringify(body)
});
};
const get = () => {
axios
.get(URL)
.then(response => {
console.log(response.data);
pass(response.data);
})
.catch(err => pass(err));
};
if (event.httpMethod == "GET") {
get();
}
};
App.js
componentDidMount() {
fetch('.netlify/functions/youtube')
.then(response => response.json())
.then(data => console.log(data));
}

this took me a minute to figure out but it's in the query string:
let thing = 123;
fetch(`/.netlify/functions/${filename}?item=${thing}`)
.then(response => response.json())
.then(json => console.log(json))
if it's a post, you will need to parse it from the query but a regular get call you can pull it out of the event.queryStringParameters

Related

How to get the data through the map and put it in the state

I wanted to use Axios get to put the contents value of 'card' and call the data and put the value in 'wordAll', but it failed.
I want to combine and store the arrays I received as an axios in the state through the map function.
Sometimes the code I wrote comes in and sometimes it doesn't. I know my code is wrong.
Please teach me the way.
const [wordAll, setWordAll] = useState([]);
useEffect(() => {
cards.map((contents) => {
axios
.get(`https/api/words/detail_list/?contents=${contents.contents}`, {
headers: {
Authorization: cookies.token,
},
})
.then((res) => {
let indata = res.data;
for (var i = 0; i < indata.length; i++) {
wordAll.push(indata[i]);
setWordAll(wordAll);
}
console.log('wordAll0', wordAll);
})
.catch((error) => {
console.log('err==>', error);
});
});
}, []);
console.log('wordAll1', wordAll);
You can keep the cards axios request promises in an array (cardsPromises) and then use Promise.all to get the values from the resolved promises.
useEffect(() => {
const cardsPromises = cards.map((contents) =>
axios.get(`https/api/words/detail_list/?contents=${contents.contents}`, {
headers: {
Authorization: cookies.token
}
})
);
Promise.all(cardsPromises)
.then((resp) => {
//resp will be an array of resolved values
setWordAll(resp);
})
.catch((error) => {
console.log("err==>", error);
});
}, []);

I am having a problem setting state with returned json data

I am doing a project messing around with The Movie Data Base Api. I am using fetch to grab saved id's (I am storing them in a fake rest api, JSON SERVER) and then looping through them and for each id I am making a fetch to retrieve the particular movie the id is associated with. I am using Promise.All to achieve this. After Pushing the data into an empty array I am able to get back what I need in a console.log() if I log the array, but the minute I try to use useState() and pass the array in it starts infinitely making requests. Maybe Someone can point me in the right direction? Thank you
let moviesToReturn = []
const [favorites, setFavorites] = useState([])
let requests = movieId.map(id => {
return new Promise((resolve, reject) => {
request({
url: `https://api.themoviedb.org/3/movie/${id.movieId}?api_key=${movieApikey}`,
method: 'GET'
},
(err, res, body) => {
if (err) { reject(err) } //function passed to the promise
resolve(body)
})
})
})
Promise.all(requests).then((body) => {
body.forEach(res => {
if (res)
moviesToReturn.push(JSON.parse(res))
console.log(moviesToReturn, 'movies to return')
return setFavorites(moviesToReturn)
})
}).catch(err => console.log(err))
You need to call the api at the initial rendering and then set the state. Therefore, you need to use useEffect having empty dependency array as follows. The way you have done it will cause the application to render it infinitely.
Additionally, setState function doesn't return anything.
useEffect(() => {
let requests = movieId.map((id) => {
return new Promise((resolve, reject) => {
request(
{
url: `https://api.themoviedb.org/3/movie/${id.movieId}?api_key=${movieApikey}`,
method: "GET",
},
(err, res, body) => {
if (err) {
reject(err);
} //function passed to the promise
resolve(body);
}
);
});
});
Promise.all(requests)
.then((body) => {
let moviesToReturn = []; /* keep moviesToReturn array here */
body.forEach((res) => {
if (res) moviesToReturn.push(JSON.parse(res));
console.log(moviesToReturn, "movies to return");
});
setFavorites(moviesToReturn);
})
.catch((err) => console.log(err));
}, []);

findOneAndUpdate returns null with client side

I'm new to mongodb and mongoose.
I have this request that works perfectly on postman (update number of reservation)
router.put("/book/:idEvent", (req, res) => {
const _idEvent = req.params.idEvent;
const places = req.body.places;
Event.findOneAndUpdate(
{ _id: _idEvent },
{
$set: { places },
},
{new:true, upsert:true},
)
.then((event) => res.json(event))
.catch((err) => res.json(err));
});
But when I call this on the client side, it insert null into attribute places.
According to mongodb documentation, it shouldn't be null when upsert&new properties are true,
I tried it but nothing changed.
I tried to send static arguments from the client side but it still returns null.
my frontend method:
export const updatePlaces = (idEvent, updatedPlaces) => (dispatch) => {
axios
.put(`http://localhost:5000/events/book/${idEvent}`, updatedPlaces)
.then((res) => dispatch(getEvents()))
.catch((err) => console.log(err));
};
i learned also that the templateId is being sent via Xhr request from the client-side and sending information using Xhr (or any Ajax-type request) converts everything to 'string': so I changed the attribute type in schema from Number to String but again it returns null.
places: { type: String},
Any idea how to solve this problem??
Looking at your postman request, you assign const places to req.body.places:
router.put("/book/:idEvent", (req, res) => {
const _idEvent = req.params.idEvent;
const places = req.body.places;
but in your client side code, you pass updatedPlaces to your request:
export const updatePlaces = (idEvent, updatedPlaces) => (dispatch) => {
axios
.put(`http://localhost:5000/events/book/${idEvent}`, updatedPlaces)
.then((res) => dispatch(getEvents()))
.catch((err) => console.log(err));
};
have you tried assigning const places to req.body.updatedPlaces?
This is probably not the final solution but try this as a next step to debug your problem:
router.put("/book/:idEvent", async (req, res) => {
const _idEvent = req.params.idEvent;
const places = req.body.places;
const event = await Event.findOneById(_idEvent):
if(!event) {
console.log("event not found", _idEvent);
// do your upsert logic here
return;
}
// this code is for debugging
if(!places) {
throw Error("You never passed a places value in the first place!")
}
const placesVal = Number.parseInt(places, 10);
if(Number.isNaN(placesVal)) {
throw Error("Not a valid number", placesVal)
}
event.places = placesVal;
const result = await event.save();
res.json(result);
});

How to use async function and export it correctly with React Native?

My question is about correctly implementing an async function to fetch data. I've a function called _getData() and I'm calling it on the componentDidMount() of a screen. But when server response is slow, switching to this screen is getting slower. So I would like to use async function for fetching data. But I'm not sure if I'm doing it correctly. Is that a correct approach? I can't be sure if it works async or not.
Here is my Api._getData() code:
const _getData = async () => {
return await axios.get("http://blabla.com/someservice", { params: someParamDataHere });
};
export const Api = {
_getData
};
and on SomeScreen.js, I also have loadData() function which calls the function above and does state updates.
loadData() {
Api._getData()
.then((response) => {
this.setState({ myData: response.data });
})
.catch((error) => {
console.log(error.response);
});
}
in componentDidMount() function of the same screen I'm calling this loadData()  function directly.
Now, is it enough to declare Api._getData() as async and using await in it, or should I change some trigger functions too?
Thank you very much for your help.
instead of async await use promises
export const getRequest = (url) => {
return new Promise((resolve, reject) => {
api
.get(url)
.then((response) => {
handleReponse(response)
.then((errorFreeResponse) => {
resolve(errorFreeResponse);
})
.catch((error) => {
reject(error);
});
})
.catch((error) => {
reject(handleError(error));
});
});
};
You are doing correct while retrieving in load Data . What you can do more is try more syntactical sugar of es6 by using async await in loadData , hence
loadData = async() =>{
try{
let response = await Api._getData();
this.setState({ myData: response.data });
} catch(err){
console.log(error.response);
}
}
Hope it helps. feel free for doubts

How can i use React's fetch to store data into a variable?

I'm using React and i need to store some Api requests into variables so that i could do some modifications.
I want to do something like this :
function getMovies() {
var moviesArr = '';
return fetch('https://api.themoviedb.org/3/movie/now_playing?api_key=4344343' +
'd61a2e5')
.then((response) => response.json())
.then((json) => moviesArr = json);
}
const currentMoviesArray = getMovies() // Then to recieve the movies data
So the const currentMoviesArray will finally bring me back the fetched data
Instead of storing it to a varibale. You can set the response to one state variable, so that you can use it every where in component.
function getMovies() {
return fetch('https://api.themoviedb.org/3/movie/now_playing?api_key=4344343' +
'd61a2e5')
.then((response) => response.json())
.then((json) => this.setState({moviesArr:json});
}
The function getMovies() returns a promise. so you can either set the values of currentMoviesArray from within the then() handler, or refactor your function with async/await which waits for a promise to settle and return a result, see both options below:
Option 1:
const currentMoviesArray = [];
function getMovies() {
fetch('https://api.themoviedb.org/3/movie/now_playing?api_key=4344343' +
'd61a2e5')
.then((response) => response.json())
.then((movies) => currentMoviesArray.push(movies));
}
Option 2:
async function getMovies() {
await fetch('https://api.themoviedb.org/3/movie/now_playing?api_key=4344343' + 'd61a2e5')
.then((response) => response.json());
}
const currentMoviesArray = getMovies();

Resources