Can' access content of an array in react-native - javascript

I'm trying to get data from a SQLite Database in React-Native (android). The function returns an Array with data.
If I try logging the array to the console, it works fine, but when I log the length of the Array to the console, it suddenly prints "0".
Functions:
getActByButton(category) {
return new Promise((resolve) => {
const activities = [];
const request = 'SELECT activity FROM activity_button WHERE category = ? AND activity IS NOT NULL';
this.initDB().then((db) => {
db.transaction((tx) => {
tx.executeSql(request, [category]).then(([tx, results]) => {
//console.log('Query COMPLETED');
var len = results.rows.length;
for (let i = len; i > 0; i--) {
activities.push(results.rows.item(i - 1));
}
resolve(activities);
})
}).then((result) => {
this.closeDatabase(db);
})
})
})
}
getIconByAct(activity_ids) {
return new Promise((resolve) => {
const icons = [];
const request = 'SELECT name, icon FROM activity WHERE id = ?';
this.initDB().then((db) => {
db.transaction((tx) => {
for (let id in activity_ids) {
tx.executeSql(request, [id]).then(([tx, results]) => {
console.log('Query COMPLETED');
var len = results.rows.length;
let icon = results.rows.item(0).icon;
let description = results.rows.item(0).name;
icons.push({ icon, description });
})
}
resolve(icons);
}).then((result) => {
this.closeDatabase(db);
})
})
})
}
Function-call:
db.getActByButton(this.props.category).then((data) => {
result_ids = data;
}).then(() => {
db.getIconByAct(result_ids).then((data) => {
console.log('DATA:');
console.log(data);
console.log(data.length);
console.log(data[1]);
})
})
Console:
How is this possible?
And how can I fix it?

Try this:
db.getActByButton(this.props.category).then((data) => {
result_ids = data;
}).then(() => {
db.getIconByAct(result_ids).then((data) => {
console.log(JSON.stringify(data));
console.log(JSON.stringify(data.length));
})
})

Related

GitHub API requests to get language usage

I'm drowning in Promises trying to get a, what I thought would be simple, piece of data back from my GitHub Repos.
All I want to do is find the percentage of languages usage across each of my repositories on GitHub. I've got it working but I am pretty confident I'm miles away from doing it correctly or as succinctly as I could if I knew what I was doing. I would really appreciate any feedback on how to go about this the right way and possibly a refactor that uses more up to date methods.
Here's my code so far (which works). Ignore how I'm outputting it for now, that's just for the proof of concept.
const username = '<GH_USERNAME>' //your username here
const apiUrl = `https://api.github.com/users/${username}/repos`;
fetch(apiUrl)
.then((response) => {
if (response.ok) {
return response.json();
}
})
.then((data) => {
languagePromises = [];
for (let i in data) {
let repo = data[i];
if (!repo['fork'] && repo['language']) {
// console.log(repo['name'], repo['language']);
let langs = repo['languages_url'];
languagePromises.push(fetch(langs))
}
}
Promise.all(languagePromises)
.then((responses) => {
let languages = [];
for (let r of responses) {
if (r.ok) languages.push(r.json())
}
Promise.all(languages)
.then((resolved) => {
let languageTotals = {};
for (langData of resolved) {
for (lang in langData) {
if (!languageTotals[lang]) {
languageTotals[lang] = 0
}
languageTotals[lang] += (langData[lang]);
}
}
// console.log(languageTotals);
let sum = 0;
for (let l in languageTotals) { sum += languageTotals[l] }
for (let l in languageTotals) {
let p = (languageTotals[l] / sum * 100).toFixed(0) + '%';
document.write(l,' ', p, '<br>');
}
});
});
})
.catch((e) => {
console.error('Error:', e);
});
Like is say. It's working but I'm basically looking for advice on how to do this properly.
Here's an example that cleans/reduces a lot of your code:
const apiUrl = `https://api.github.com/users/${username}/repos`;
fetchRepos(apiUrl)
.then((data) => {
return (data
.filter(repo => !repo.fork && repo.language)
.map(repo => ghFetchJson(repo.languages_url))
)
)
.then(languageResults => {
const languageTotals = new Map();
for (const langData of languageResults) {
for (const [lang, count] of Object.entries(langData)) {
languageTotals.set(lang, (languageTotals.get(lang) ?? 0) + count);
}
}
const sum = Array.from(languageTotals).reduce((acc, cur) => acc+cur[0], 0);
for(const [language, count] of languageTotals) {
const p = (count / sum * 100).toFixed(0) + '%';
console.log('%s: %i', language, count);
}
});
}).catch((e) => {
console.error('Error:', e);
});
async function ghFetchJson(url) {
const res = await fetch(url);
return res.json();
}
const username = 'octocat'
const apiUrl = `https://api.github.com/users/${username}/repos`;
fetch(apiUrl)
.then((response) => {
if (!response.ok) {
throw new Error('Request failed')
}
return response.json();
})
.then((repos) => repos.filter(repo => !repo['fork'] && repo['language']).map(repo => fetch(repo['languages_url'])))
.then(e => Promise.all(e))
.then((resps) => resps.filter(r => r.ok).map(r => r.json()))
.then(e => Promise.all(e))
.then((resolved) => {
console.log(resolved)
const languageTotals = {};
for (const langData of resolved) {
for (const lang in langData) {
if (!languageTotals[lang]) {
languageTotals[lang] = 0
}
languageTotals[lang] += (langData[lang]);
}
}
let sum = 0;
for (const lang of languageTotals) {
sum += lang
}
for (const lang of languageTotals) {
let p = (lang / sum * 100).toFixed(0) + '%';
document.write(l, ' ', p, '<br>');
}
})
.catch((e) => {
console.error('Error:', e);
});

Assigned returned value from function chain into a variable in javascript

Hello I'm having a little problem when I try to assign returned value from function into a variable. I've tried this code with a console.log and it displays the right result but when I want to assign this result to a variable it gives undefined value. So here is the code and can u explain it to me what am I doing wrong because I'm a javascript noobie.
const onDataChange = (items) => {
let products = [];
let images = listFromStorage();
//a function call that displays undefined value but should return array
console.log(images);
items.forEach((item) => {
let key = item.key;
let data = item.val();
products.push({
key : key,
title : data.title,
before : data.before,
after : data.after
})
})
setProductList(...productList, products);
}
const listFromStorage = () => {
let storageRef = firebaseService.getStorage().ref().child('/posts/products');
let images = [];
storageRef.listAll().then(function (res) {
res.items.forEach((imageRef) => {
imageRef.getDownloadURL().then((url) => {
images.push({
url : url
});
});
});
return images;
})
.catch(function (error) {
console.log(error);
});
}
You need to not only wait for the asynchronous code to finish, but you need to also return a value from listFromStorage to assign.
const onDataChange = async (items) => { // <-- declare async
const products = [];
const images = await listFromStorage(); // <-- await result
console.log(images);
items.forEach((item) => {
const key = item.key;
const data = item.val();
products.push({
key: key,
title: data.title,
before: data.before,
after: data.after
})
})
setProductList(...productList, products);
}
const listFromStorage = () => {
const storageRef = firebaseService
.getStorage()
.ref()
.child('/posts/products');
const images = [];
return storageRef // <-- return Promise chain
.listAll()
.then(function (res) {
res.items.forEach((imageRef) => {
imageRef.getDownloadURL().then((url) => {
images.push({ url });
});
});
return images;
})
.catch(function (error) {
console.log(error);
});
}

Passing response data to an array

How can I pass fetched data to array called users? I've tried using this.users = data.data, then console.log(users) and nothing is showing up.
Also I am trying to map response, I am getting error in console Uncaught TypeError: fetchData.map is not a function
const users = [];
const fetchData = () => {
axios.get('https://reqres.in/api/users')
.then(({data}) => {
this.users = data.data;
console.log(data);
})
}
fetchData();
const mapUsers = fetchData.map((item) => {
return {
avatar: item.avatar
}
})
May be you would need to move map inside to the callback
let users = [];
const fetchData = () => {
axios.get("https://reqres.in/api/users").then(({ data }) => {
users = data.data;
const mapUsers = users.map((item) => {
return {
avatar: item.avatar,
};
});
console.log("mapUsers", mapUsers);
});
};
fetchData();
or
let users = [];
const fetchData = () => {
return axios.get("https://reqres.in/api/users").then(({ data }) => {
return data.data;
});
};
fetchData().then((data) => {
console.log(data);
const mapUsers = data.map((item) => {
return {
avatar: item.avatar,
};
});
console.log("mapUsers", mapUsers);
});

Promise should return data after end two for loop

which get data from API:
const countries = [
'Spain',
'England',
];
const getLeagueID = () => {
const newData = [];
return new Promise(resolve => {
for (let i = 0; i < countries.length; i++) {
getApi(`https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=${countries[i]}`)
.then(({ countrys }) => {
countrys.forEach((league, index) => {
if (league.strSport === 'Soccer') {
const getData = {
strSport: league.strSport,
strLeague: league.strLeague,
};
newData.push(getData);
}
if (index === countrys.length - 1 && i === countries.length - 1) {
resolve(newData);
}
});
})
.catch(err => {
console.log(err);
});
}
});
};
In first for loop I doing increment by countries from list.
When Api return data I create second foreach method. Inside this method I get data and push it to arra newData. The problem is with resolve:
if (index === countrys.length - 1 && i === countries.length - 1) {
resolve(newData);
}
I don't know how to write instruction if, which wait for the end foreach and for loop. My instruction if is wrong because not return all data. First time return 3 records, next time 7 records.
It's work, but sure that it can be improved
const getLeagueID = () => {
return new Promise((resolve, reject) => {
const promises = [];
for (let i = 0; i < countries.length; i++) {
promises.push(
getApi(`https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=${countries[i]}`)
);
}
Promise.all(promises)
.then(res => {
const newData = [];
res.map(row => {
const data = JSON.parse(row);
const {countrys} = data;
countrys.forEach((league, index) => {
if (league.strSport === 'Soccer') {
const getData = {
strSport: league.strSport,
strLeague: league.strLeague,
};
newData.push(getData);
}
});
});
resolve(newData);
})
.catch(err => {
console.log(err);
reject(err);
});
});
}

react native : what is the way to send data from promise function into const? got some error while try console.log

what is the way to send the data from "Get_Successor_Zones_From_Table " promise function
into variable const data ?
i need only the "Zone_Name".
this data is an list of objects and they looks like this :
[{"Zone_ID":66,"Zone_Name":"Herzel"},{"Zone_ID":0123,"Zone_Name":"Zelda"}]
async Get_Successor_Zones_From_Table() {
const Zone_Names = [];
const promise = new Promise((resolve, reject) => {
db.transaction((tx) => {
tx.executeSql(
'SELECT Successor_Zones FROM tblUserConnectResponseData',
[],
(_, result) => {
var len = result.rows.length;
for (let i = 0; i < len; i++) {
let row = result.rows.item(i);
// console.log();
const { Successor_Zones } = row;
Zone_Names.push({
Successor_Zones,
});
}
resolve({
isAny: true,
Zone_Names: row,
});
},
(_, err) => {
reject(err);
}
);
});
});
return promise;
}
i add button like this :
<TouchableOpacity
onPress={() => {
this.setState({ activeIndex: 0 });
this.Get_Successor_Zones_From_Table.then((result) => {
console.log(result);
}).catch((error) => console.log(error));
}}
activeOpacity={1}
style={
this.state.activeIndex === 0
? styles.button
: styles.button2
}
>
<Text style={styles.textButton}>list of places</Text>
</TouchableOpacity>
const [zoneNames, setZoneNames] = useState();
const Get_Successor_Zones_From_Table = () => {
let Zone_Names = [];
return new Promise((resolve, reject) => {
db.transaction(tx => {
// ...
});
});
};
And then
Get_Successor_Zones_From_Table.then(data => setZoneNames(data));
Your declaration
async Get_Successor_Zones_From_Table() {
Call
this.Get_Successor_Zones_From_Table.then((result) => {
console.log(result)
}).catch(error => console.log(error))

Categories

Resources