can't get data form array - javascript

I try to get data from the array but I get undefined
please check the image of my problem
I don't know what I'm missing
please help
I have an array called nameTable of string
when I console.log(this.nameTable) I got this : check the image please
enter image description here
and when I click to arrow I got this : check image please
enter image description here
the problem is the table has 5 element I want to show them so I make for loop to do that
for (let i = 0; i < 5; i++){
console.log(this.nameTable[i])
}
but us you can see in the image I got undefined
enter image description here
here the code :
employeeL:Array<Awinjard> = [];
inv_agentTab: Array<Inv_agent> = [];
drafbiesTab: Array<Drafbies> = [];
nameemployee: string = "";
inv_agentNombre: number = 0;
matriculeTable: Array<number> = [];
nameTable:Array<string> = [];
validatationTable: Array<number> = [];
ngOnInit() {
this.folder = this.activatedRoute.snapshot.paramMap.get('id');
this.awinjard.getAwinjardMatricule().subscribe(res => {
this.inv_agentTab = res as Array<Inv_agent>
this.inv_agentTab.forEach(element => {
this.matriculeTable[this.inv_agentNombre] = element.AGENT;
this.validatationTable[this.inv_agentNombre] = element.VLD;
this.inv_agentNombre++;
this.awinjard.getAwinjardNameAr().subscribe(res2 => {
this.drafbiesTab = res2 as Array<Drafbies>
this.drafbiesTab=this.drafbiesTab.filter((employee)=>employee.DECAFFE==element.AGENT)
this.nameemployee = this.drafbiesTab[0].AR_DELAFFE;
this.nameTable.push(this.nameemployee);
})
});
for (let i = 0; i < 5; i++){
// here the problem I can't get the data form nameTable array
console.log(this.nameTable[i])
let awin= <Awinjard> {
matricule: this.matriculeTable[i],
fullname: this.nameTable[i],
status: true,
done: 1,
mustBeDone:40
}
this.employeeL.push(awin);
}
})
}

You have subscribed to getAwinjardNameAr and before that response, you are trying to access the nameTable array, which is why you get undefined. #raishav-hanspal's solution is right to solve your issue, but a code change can keep things straightforward. I suggest you to write that code inside your for loop inside your subscribe. Here's the alteration:
this.awinjard.getAwinjardNameAr().subscribe(res2 => {
this.drafbiesTab = res2 as Array<Drafbies>
this.drafbiesTab=this.drafbiesTab.filter((employee)=>employee.DECAFFE==element.AGENT)
this.nameemployee = this.drafbiesTab[0].AR_DELAFFE;
this.nameTable.push(this.nameemployee);
let awin= <Awinjard> {
matricule: this.matriculeTable[this.inv_agentNombre],
fullname: this.nameemployee,
status: true,
done: 1,
mustBeDone:40
}
this.employeeL.push(awin);
})

You can move the code where you're logging nameTable[] inside the subscribe (where you are pushing the values into nameTable[]).
A complete solution is to use complete in subscribe() -->
this.awinjard.getAwinjardNameAr().subscribe(res2 => {
this.drafbiesTab = res2 as Array<Drafbies>
this.drafbiesTab=this.drafbiesTab.filter((employee)=>employee.DECAFFE==element.AGENT)
this.nameemployee = this.drafbiesTab[0].AR_DELAFFE;
this.nameTable.push(this.nameemployee);
},err => {console.log(err)}, ()=> {
for (let i = 0; i < 5; i++){
// here the problem I can't get the data form nameTable array
console.log(this.nameTable[i])}})
});
You can read more on https://angular.io/guide/observables

Related

Merging 2 arrays, with specified items

I stuck with joining 2 arrays.
I fetch data from 2 API, in response I got 2 different arrays, what I want to achive is one array with joined and selected arguments.
const skills = ref([]);
const entries = axios.get(`https://cdn.contentful.com/spaces/${space_id}/environments/${environment_id}/entries?access_token=${access_token}`);
const assets = axios.get(`https://cdn.contentful.com/spaces/${space_id}/environments/${environment_id}/assets?access_token=${access_token}`);
axios
.all([entries, assets])
.then(
axios.spread((...responses) => {
const responseEntries = responses[0].data.items.map(
(item) => item.fields
);
const responseAssets = responses[1].data.items.map(
(item) => "https:" + item.fields.file.url
);
const checkEntries = Array.isArray(responseEntries);
const checkAssets = Array.isArray(responseAssets);
console.log(checkEntries);
console.log(checkAssets);
console.log(responseEntries);
console.log(responseAssets);
for (let i = 0; i < responseEntries.length; i++) {
skills[i].value = [
responseAssets[i],
responseEntries[i].title,
responseEntries[i].list,
responseEntries[i].description,
];
}
})
)
.catch((error) => console.log(error));
I'm getting error:
TypeError: Cannot set properties of undefined (setting 'value')
Here is what I got in console, and the how arrays looks
Thank you! Your answer help me to rethink that problem and finally I solved it in different way I added a value to first array.
for (let i = 0; i < responseEntries.length; i++) {
responseEntries[i].url = responseAssets[i];
}
skills.value = responseEntries;
Your problem is certainly inside the for loop, where you try:
skills[i].value = [...]
at that point, skills[i] doesn't exist so you have to initialize it before into an object, so:
for (let i = 0; i < responseEntries.length; i++) {
skills.value[i] = {}
skills.value[i] = [
responseAssets[i],
responseEntries[i].title,
responseEntries[i].list,
responseEntries[i].description,
];
}
I still don't understand the first line, though, const skills = ref([]); where, imho, should just be const skills = []

How to make react stop duplicating elements on click

The problem is that every time I click on an element with a state things appear twice. For example if i click on a button and the result of clicking would be to output something in the console, it would output 2 times. However in this case, whenever I click a function is executed twice.
The code:
const getfiles = async () => {
let a = await documentSpecifics;
for(let i = 0; i < a.length; i++) {
var wrt = document.querySelectorAll("#writeto");
var fd = document.querySelector('.filtered-docs');
var newResultEl = document.createElement('div');
var writeToEl = document.createElement('p');
newResultEl.classList.add("result");
writeToEl.id = "writeto";
newResultEl.appendChild(writeToEl);
fd.appendChild(newResultEl);
listOfNodes.push(writeToEl);
listOfContainers.push(newResultEl);
wrt[i].textContent = a[i].data.documentName;
}
}
The code here is supposed to create a new div element with a paragraph tag and getting data from firebase firestore, will write to the p tag the data. Now if there are for example 9 documents in firestore and i click a button then 9 more divs will be replicated. Now in total there are 18 divs and only 9 containing actual data while the rest are just blank. It continues to create 9 more divs every click.
I'm also aware of React.Strictmode doing this for some debugging but I made sure to take it out and still got the same results.
Firebase code:
//put data in firebase
createFileToDb = () => {
var docName = document.getElementById("title-custom").value; //get values
var specifiedWidth = document.getElementById("doc-width").value;
var specifiedHeight = document.getElementById("doc-height").value;
var colorType = document.getElementById("select-color").value;
parseInt(specifiedWidth); //transform strings to integers
parseInt(specifiedHeight);
firebase.firestore().collection("documents")
.doc(firebase.auth().currentUser.uid)
.collection("userDocs")
.add({
documentName: docName,
width: Number(specifiedWidth), //firebase-firestore method for converting the type of value in the firestore databse
height: Number(specifiedHeight),
docColorType: colorType,
creation: firebase.firestore.FieldValue.serverTimestamp() // it is possible that this is necessary in order to use "orderBy" when getting data
}).then(() => {
console.log("file in database");
}).catch(() => {
console.log("failed");
})
}
//get data
GetData = () => {
return firebase.firestore()
.collection("documents")
.doc(firebase.auth().currentUser.uid)
.collection("userDocs")
.orderBy("creation", "asc")
.get()
.then((doc) => {
let custom = doc.docs.map((document) => {
var data = document.data();
var id = document.id;
return { id, data }
})
return custom;
}).catch((err) => {console.error(err)});
}
waitForData = async () => {
let result = await this.GetData();
return result;
}
//in render
let documentSpecifics = this.waitForData().then((response) => response)
.then((u) => {
if(u.length > 0) {
for(let i = 0; i < u.length; i++) {
try {
//
} catch(error) {
console.log(error);
}
}
}
return u;
});
Edit: firebase auth is functioning fine so i dont think it has anything to do with the problem
Edit: This is all in a class component
Edit: Clicking a button calls the function createFileToDb
I think that i found the answer to my problem.
Basically, since this is a class component I took things out of the render and put some console.log statements to see what was happening. what i noticed is that it logs twice in render but not outside of it. So i took the functions out.
Here is the code that seems to fix my issue:
contain = () => {
const documentSpecifics = this.waitForData().then((response) => {
var wrt = document.getElementsByClassName('writeto');
for(let i = 0; i < response.length; i++) {
this.setNewFile();
wrt[i].textContent = response[i].data.documentName;
}
return response;
})
this.setState({
docs: documentSpecifics,
docDisplayType: !this.state.docDisplayType
})
}
As for creating elements i put them in a function so i coud reuse it:
setNewFile = () => {
const wrt = document.querySelector(".writeto");
const fd = document.querySelector("#filtered-docs");
var newResultEl = document.createElement('div');
newResultEl.classList.add("result");
var wrtEl = document.createElement('p');
wrtEl.classList.add("writeto");
fd.appendChild(newResultEl);
newResultEl.appendChild(wrtEl);
}
The firebase and firestore code remains the same.
the functions are called through elements in the return using onClick.

How do I console.log json information?

quite new to working with both api's and javascript. I'm trying to console.log out the amount of times a friend of mine has died in rust, but all items are named "name:" An img of what I mean:
I'm using axios to call the api, here's the code:
var statsApi = 'http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?';
var statsAppId = 'appid='+252490+'&'
var statsSteamApiKey = 'key='+process.env.STEAM_API+'&';
var statsUserArg = 'steamid='+userID;
var steamStatsApi = statsApi + statsAppId + statsSteamApiKey + statsUserArg;
axios
.get(steamStatsApi)
.then((res) =>{
message.channel.send("AAAA");
// console.log(res['data']['playerstats']['stats']['name' == 'deaths']);
for(re in res['data']['playerstats']['stats']) {
if(re['name'] === 'deaths') {
console.log('test');
console.log(re['value']);
}
else {
console.log('Fel');
}
}
})
.catch((err) => {
console.error('Error:', err);
})
Again if anyone knows how to get the amount of 'deaths' I'd be super grateful.
Turns out it was quite easy, if anyone has this problem just use the following code which I am about to provide:
var index = -1;
for(var i = 0; i < Object.keys(res['data']['playerstats']['stats']).length; i++) {
if(res['data']['playerstats']['stats'][i]['name'] === 'deaths') {
index = i;
var userDeaths = res['data']['playerstats']['stats'][index]['value'];
break;
}
}
What this does is that it loops trough every object named "name:" until it finds 'deaths' in one of them. I change i to that and now i'm able to print out the value which i'm looking for.
Please check this code:
let res = [{ name: "deaths", value: 2694}, {name:"bullet_fired", value: 343328}];
let i = 0;
for(i=0;i<res.length;i++){
if(res[i].name =="deaths"){
console.log(res[i].value);
}
}
Here res variable will contain your json values.

Why an element in an object is always assigned the same value in a loop | vueJS

I think I have a problem understanding how javascript or more precisely vuejs in this case works...
the following code is given:
....
data() {
campaigns: [{id: 1, name: 'Campaign 1'}, {id: 2, name: 'Campaign 1'}]
campaignsWithEventSettings: [0, 1] //these are the indexes for campaigns
},
methods: {
saveOrUpdate() {
let campaigns = [];
this.campaignsWithEventSettings.map(x => {
let campaign = this.campaignsSettings[x];
campaign.event_settings = true;
console.log(this.campaigns[x].id) //screenshot with the result is attached below
campaign.id = this.campaigns[x].id;
campaigns.push(campaign);
});
//that gives the same result
/*for (let i = 0; i < this.campaignsWithEventSettings.length; i++) {
let idx = this.campaignsWithEventSettings[i];
let campaign = this.campaignsSettings[idx];
campaign.event_settings = true;
campaign.id = this.campaigns[idx].id;
campaigns.push(campaign);
}*/
let settings = [];
settings.push({eventId: this.eventId});
settings.push({campaigns: campaigns});
axios.post('/events/campaigns', settings).then(resp => {
console.log(resp)
})
},
}
....
the problem is that in the end, all campaigns have the same id, although when running console.log the log ids are different/correct.
so in other words at each loop, all campaigns in the array receive a new id (the last one).
console.log
screenshot_console
request
screenshot_request_data
so I will quote what the problem is and I put the link with more detailed information.
When you use a variable that is declared outside the scope the variable is going to be used in, it will use the value that variable has at the time it runs. It doesn't get a copy of the value at the time the closure is setup. If you think of closures as pointers rather than values, maybe that will help.
sorce: https://dzone.com/articles/why-does-javascript-loop-only-use-last-value
this means that the variable that your let campaign = this.campaignsSettings[x]; is using is always the last one of the X. Because your X is the variable out of the scope, this is very often when you try to output the index of an loop.
A quick solution is to wrap in a function!
for(let x of this.campaignsWithEventSettings){
(function (newX){
let campaign = this.campaignsSettings[newX];
campaign.event_settings = true;
campaign.id = this.campaigns[newX].id;
campaigns.push(campaign);
})(x);
}
or something like
for(let x of this.campaignsWithEventSettings){
try{throw x}
catch(newX){
let campaign = this.campaignsSettings[newX];
campaign.event_settings = true;
console.log(this.campaigns[newX].id)
campaign.id = this.campaigns[newX].id;
campaigns.push(campaign);
}
}
I'd do the following:
let campaigns = this.campaignsWithEventSettings.map(x => {
let campaign = this.campaignsSettings[x];
campaign.event_settings = true;
campaign.id = this.campaigns[x].id;
return campaign
});

Async object does not get returned from getInitialProps despite success elsewhere

I'm just starting to figure out React by putting together a bit of code from different parts, and from an online course.
I'm using React, Next and Axios to get an API from a cryptocurrency server.
The main issue I'm facing is:
I am able to console.log(coinObjects) under getInitialProps, and it displays the object correctly
Despite this, coinObjects does not get rendered in {this.props.coinObjects}
As a possible clue, linksArr does get rendered in {this.props.linksArr}
The code I have is as follows:
class MainIndex extends Component {
static async getInitialProps(props) {
// setup - empty array and list of coins
const coinList = ["NEO", "ETH", "BTC"];
const numCoins = coinList.length;
const coinObjects = [];
const linksArr = [];
const isServer = typeof window === "undefined";
// API GET
const baseUrl = "https://min-api.cryptocompare.com/data/histohour?";
for (let coinName of coinList) {
linksArr.push(
baseUrl.concat("fsym=", coinName, "&tsym=", "USD", "&limit=", "3")
);
}
const getObj = async linksArr => {
try {
let res = await axios.all(linksArr.map(l => axios.get(l)));
for (let i = 0; i < linksArr.length; i++) {
coinObjects[coinList[i]] = res[i].data.Data;
}
} catch (err) {
console.error(err);
}
};
await getObj(linksArr);
console.log(coinObjects);
// Return updated arrays
if (isServer) {
return { coinObjects, numCoins, linksArr };
} else {
return {};
}
}
render() {
return (
<Layout>
<h2>
CoinObject has {this.props.coinObjects.length} coins
// Returns 0
<br />
LinksArr has {this.props.linksArr.length} links
// Returns 3
</h2>
</Layout>
);
}
}
Could anyone please help me? I've exhausted all the Google searches, Stackoverflow posts and coding friends that I can find (just 1). I can't figure out what's wrong, and I hope that this isn't a silly question because I've been tweaking and changing things extensively, but have yet to figure out what's wrong.
Here the coinObject is set to an array:
const coinObjects = [];
But later is treated as an Object:
coinObjects[coinList[i]] = res[i].data.Data;
That means that you would want to add to the array like this:
for (let i = 0; i < linksArr.length; i++) {
let data = res[i].data.Data;
let name = coinList[i];
coinObjects.push({ name: name, data: data });
}

Categories

Resources