Variable.map is not a function React Javascript - javascript

I am working on app and I am trying to extract three attributes of this string (I thought it was an array of objects is filteredResultsJSON, but it is a string) :
Well, when I want to get the news of a given section I am using this code:
export default function getNewsFilteredBySection (sectionSearched="") {
const URL= `https://api.nytimes.com/svc/mostpopular/v2/viewed/7.json?api-key=${API_KEY}`;
return fetch(URL)
.then(res=>res.json())
.then(response=> {
const { data = [] } = response;
if(Array.isArray(data)){
const {results} = response;
const filteredResults = results.filter(obj => {
return obj.section === sectionSearched;
});
const filteredResultsJSON = JSON.stringify(filteredResults);
const name = typeof(filteredResultsJSON);
console.log(name);
return filteredResultsJSON;
}
})
};
I did JSON.stringify(filteredResults) because I saw it when doing console.log()as an [Object Object] and I wanted to be able to read the information and to loop through it to be able to extract it.
So I am using this code to extract the attributes I want for each news:
export function getNewsAttributes (filteredResultsJSON=[]) {
const newsAttributes = filteredResultsJSON.map(filteredResultJSON=>{
const { title, abstract, url } = filteredResultJSON;
console.log(title, abstract, url);
return {title, abstract, url};
});
return newsAttributes;
};
But it returns the following error:
I have been researching and I totally think the matter is about JSON.Stringify(filteredResults). How could I maintain that variable as an object, being able to read it and extract the information from it?
I am going to use it like this, after an onClick event:
function showEvent (e) {
const sectionSearched = e.target.innerText;
const filteredResultsJSON = getNewsFilteredBySection(sectionSearched);
const newsAttributes = getNewsAttributes(filteredResultsJSON);
}
Thanks a lot :)

I solved it with this code:
export default function getNewsFilteredBySection (sectionSearched="") {
const URL= `https://api.nytimes.com/svc/mostpopular/v2/viewed/7.json?api-key=${API_KEY}`;
return fetch(URL)
.then(res=>res.json())
.then(response=> {
const { data = [] } = response;
if(Array.isArray(data)){
const {results} = response;
const filteredResults = results.filter(obj => {
return obj.section === sectionSearched;
});
console.log(filteredResults);
return filteredResults;
}
})
};
Finally I didnt need to do JSON.Stringify(filteredResults). However I am having this two errors and I dont know why, my app works:
Any idea? Thanks a lot :)

You need to add async
export default async function getNewsFilteredBySection (sectionSearched=""){ ...
showEvent = async (e) => { ...
and await
const filteredResultsJSON = await getNewsFilteredBySection(sectionSearched);

Related

Confused by async behavior

I'm using a try/catch to make some fetch requests, then I am extracting the title from the HTML and adding it to my object 'sleekResponse'
When I try to parse the body and add it to that object I'm having issues with the return value not including the title that I extracted from the HTML
I know this has something to do with asynchronicity, or my shallow understanding of Promises, but I can't tell why the return value is different from the value it's logging just before it's sent.
async function fetchUrl(url) {
console.log(url);
try {
const myInit = {
mode: 'cors'
}
let sleekResponse = {};
await fetch(url, myInit).then(function (response) {
sleekResponse.redirected = response.redirected;
sleekResponse.status = response.status;
return response;
})
.then((response) => titleWait(response))
.then((res) => sleekResponse.title = res)
function titleWait(response) {
Promise.resolve(response.text()).then((res) => {
a = res.split('<title>');
b = a[1].split('</title>')
sleekResponse.title = b[0];
return sleekResponse;
})
console.log(sleekResponse);
return sleekResponse;
}
console.log(sleekResponse); // This logs the correct value
return sleekResponse; // when it's returned it doesn't show the title that was added
} catch (err) {
return `${err}`;
}
}
I've tried so many things I don't remember everything that I tried. I know that I'm missing something that might be obvious, but I still don't understand why the console.log value is different from the value returned one line later.
The main issue is that titleWait doesn't return its own promise:
function titleWait(response) {
return Promise.resolve(response.text()).then((res) => {
a = res.split('<title>');
b = a[1].split('</title>')
sleekResponse.title = b[0];
return sleekResponse;
});
}
It's still a very convoluted way to write it. This is better:
async function titleWait(response) {
const res = await response.text());
const a = res.split('<title>');
const b = a[1].split('</title>')
sleekResponse.title = b[0];
return sleekResponse;
}
i hope i can a litel help
this basic fetch();
const response = await fetch('your url')
const data = await response.json();
console.log(data);

React jsonserver promise result issue

I am creating a react/ redux app with json fake api server I am trying to add a login and trying to get data from json fake api server, data is showing and all ok , but data is always resulting as a promise and the required data is inside the promise. i tried many ways to distructure but throwing errors , could anyone help me on this,
my axios request
const urlss = "http://localhost:5000/users";
export const userslist = async () => {
const r = await axios.get(urlss);
const data = r.data;
return data;
};
const newout2 = userslist();
const newout = newout2;
console.log(newout);
the place where I am using it
export const login = (credentials) => (dispatch) => {
return new Promise((resolve, reject) => {
const matchingUser =
newout2 &&
newout2.find(({ username }) => username === credentials.username);
if (matchingUser) {
if (matchingUser.password === credentials.password) {
dispatch(setUser(matchingUser));
resolve(matchingUser);
} else {
dispatch(setUser(null));
reject("Password wrong");
}
} else {
dispatch(setUser(null));
reject("No user matching");
}
});
};
i am getting this error
You are using then in your userslist method while awaiting in an async method. drop the then and just use proper await inside an async method.
const urlss = "http://localhost:5000/users";
export const userslist = async () => {
const r = await axios.get(urlss);
const data = r.data;
return data;
};

How can I return the response of the Axios Post in React?

I have a little problem.
I have a post function in ReactJS (totally working). I wanna have the response of it outside this function, right where I called it. How can I do that?
async function confereInicial(idAluno,idDisciplina){
return await Axios.post("http://localhost:3001/api/check",{
idAluno: idAluno,
idDisciplina: idDisciplina}).then((response)=> {
});
}
//please ignore the way I call and read my function. it's confusing but I just wanna console.log the data outside my function. ignore the map etc
return (
<div>
{
dados.state.nodesPadrao.map(p => {
confereInicial(1,p.id).then(data => console.log(data)); //how should I do that?
app.post("/api/check",(req,res) => {
const idAluno = req.body.idAluno;
const idDisciplina = req.body.idDisciplina;
const sqlSelect = "SELECT * FROM `disciplinas_feitas` WHERE id_aluno = ? AND id_disciplina = ?;"
db.query(sqlSelect,[idAluno,idDisciplina],(err,result) => {
res.send(result);
});
});
may someone please help me?
this should work for you and you can put it into a variable, you don't need to put it into a map function when you are not returning a valid JSX element from it.
const dataArray = [];
async function confereInicial(idAluno, idDisciplina) {
return axios.post("http://localhost:3001/api/check", {
idAluno: idAluno,
idDisciplina: idDisciplina
});
}
const getData = () => {
dados.state.nodesPadrao.forEach(async (p) => {
const i = await confereInicial(1, p.id);
console.log("ITEM", i);
dataArray.push(i);
});
};
useEffect(() => {
getData(); // can be called onClick or anywhere you want (make sure don't call on each re-render)
}, []);
console.log(dataArray);
I think you want
function confereInicial(idAluno,idDisciplina) {
return Axios.post("http://localhost:3001/api/check",{
idAluno: idAluno,
idDisciplina: idDisciplina
});
}
This will return a Promise, so confereInicial(1, p.id).then(response => console.log(response.data)) should work.

Can something act both as an object and a function in JS?

I'm trying to create a programmatic interface to my api, I have the following routes
'api/location/:locationId/users' get, post
'api/location/:locationId/users/:userId' get, post, put
I would like to to use it like this
var myApi = new API('baseUrl');
myApi.api.location(locationId).users.get()
myApi.api.location(locationId).users.post(data)
myApi.api.location(locationId).users(userID).get()
myApi.api.location(locationId).users(userID).post(data)
myApi.api.location(locationId).users(userID).put(data)
so I started writing the class and realized it's not straight forward
class API{
constructor(baseUrl) {
this.axios = axios.create({ baseURL });;
}
this.api = {
location: (locationId) => {
users: ...(stuck)
}
}
}
I know there's different ways of doing it, but I am wondering if it's "possible" to have something act both as a function and object in javascript
ie.
var a = ..?..
a(blah) // returns an output
a.get(blah) // returns an output
It certainly is possible:
var myObj = {
someFunc: () => "foo"
}
myObj.someFunc.bar = "baz";
console.log(myObj.someFunc());
console.log(myObj.someFunc.bar);
Functions are objects just like almost everything else in JavaScript. That means you can add properties to them.
Got it. thanks #Cerbrus
class API {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.api = {
location: (locationId) => ({
users: (() => {
var a = (userId) => ({
get: () => `${this.baseUrl}/api/location/${locationId}/users/${userId}`
})
a.get = () => `${this.baseUrl}/api/location/${locationId}/users`;
return a
})()
})
}
}
}
var myApi = new API('baseUrl');
myApi.api.location('locationId').users.get()
// "baseUrl/api/location/locationId/users"
myApi.api.location('locationId').users('userId').get()
// "baseUrl/api/location/locationId/users/userId"

How to use Fetch queries in a loop?

I make a request to the server via a map with different urls, then I set the data in State and use it for output. I want the requests to be consecutive but sometimes they do not work correctly and get bugs, how to write the code for normal data retrieval?
const urlList = ["countries", "states", "cities", "users"];
componentDidMount() {
urlList.map( (url, index) => {
return servicesAPI.getResourse(url).then( (body) => {
index !== 3 ? this.setState({
dataAPI : [...this.state.dataAPI, body] }) :
this.setState({
dataAPI : [...this.state.dataAPI, body],
loaded: true
})
})
})
export default class ServicesAPI {
_apiBase = `http://localhost:3001/`;
async getResourse(url) {
const res = await fetch(`${this._apiBase}${url}`);
if (!res.ok) {
throw new Error(`Could not fetch ${url}` +
`, received ${res.status}`)
}
return await res.json();
}
Use of Promise.all();
componentDidMount() {
const fetchPromises = [];
urlList.forEach( (url, index) => {
fetchPromises.push(servicesAPI.getResourse(url));
});
const allResourcesPromise = Promise.all(fetchPromises);
allResourcesPromise.then(data => {
// list with responses
}).catch(err => {
console.log(err.toString());
});
}
Sample example:
https://jsbin.com/vevufumano/1/edit?html,js,console,output
Also instead of then, where is possible, you can use async/await for more cleaner code.

Categories