I'm new to JavaScript and NodeJS, and I need to solve this issue quickly.
connection(getSQL2)
.then((table)=> {
table.forEach(row=> {
let obj = {
countryid: row.IdPais,
country: row.NombrePais
};
data.push(obj);
});
});
console.log(obj);
When I try to display the object using console.log, I get undefined, which seems pretty obvious. But what would be an easy way to get it to display the Object 'obj' that was created above?
UPDATE: Just to clarify, console.log is used here only as an example. I need to access the object from outside that function however I can.
Thanks in advance!
Two things going on here.
1) You're using a promise and promises asynchronously resolve. Good rule of thumb is any code that ends with .then(...) is going to be a promise. What that means is that code underneath it can execute before the promise is finished and if it reads those values before the promise has finished resolving they will be read as undefined.
2) You use the let keyword to define your variable which means it will only be defined in the scope:
row => {
let obj = {
countryid: row.IdPais,
country: row.NombrePais
};
data.push(obj);
// Show the object where it is defined
console.log(obj);
}
you can create a global variable, and assign the value to that variable inside the that function.
Then, you will be able to access the variable obj outside the function also.
var temp;//declare a global variable here.
connection(getSQL2)
.then((table)=> {
table.forEach(row=> {
let obj = {
countryid: row.IdPais,
country: row.NombrePais
};
data.push(obj);
temp = obj;//assign value to global variable here
});
});
console.log(temp);//you can access the 'obj' using temp
Hope this helps you.
You need to do this:-
async database()
{
try {
const table= await connection(getSQL2);
if (table!== null)
{
table.forEach(row=> {
let obj = {
countryid: row.IdPais,
country: row.NombrePais
};
console.log('This will resolve the promise',obj);
}
else
{
//anything needed
}
}
catch (error)
{
// Error retrieving data
}
}
async and await are the keywords used in parallel. await keyword will not allow the control to go down until data is fetched.
Related
I have a JS module that is a function that fetches Issue data from our company Github, that I then want assigned to a variable:
import { request } from "https://cdn.skypack.dev/#octokit/request";
let issueData
async function getIssues() {
const issueAPI = await request("GET repos/{owner}/{repo}/issues", {
baseUrl: "https://company.com/api/v3/",
owner: "me",
repo: "exampleRepo",
});
window.issueData = issueAPI.data
return issueAPI.data
}
export { getIssues, issueData }
I can't seem to get the issueAPI.data to assign to my variable issueData? What's going wrong here? I have a feeling it's something to do with the promises/async or scope but just can't work it out.
You are assigning issueAPI.data to a window variable called issueData, which is not the same variable that you have defined with let on your snippet. If you want to assign to your declared variable, you just need to do this.
let issueData = await getIssues()
If there are no other errors in the function, this should correctly assign what you want to your declared variable.
Also you can drop the window.issueData = issueAPI.data unless you really want to have that accesible from the window object.
EDIT: As Jeremy points out, this would require top-level await. A workaround also provided by Jeremy:
let issueData
( async () => { issueData = await getIssues() })()
Imagine that you have a lot of properties in a component:
let a = 'foo';
let b = 'bar';
// ...
let z = 'baz';
You then want to do something like update all of them from an external callback, like in another library (i.e. something that isn't and can't be a Svelte component itself).
A simple use case is just an AJAX method to load in a bunch of data (assume this ajax function works and you can pass it a callback):
onMount(async function() {
ajax('/data', function(data) {
a = data.a;
b = data.b;
// ...
z = data.z;
});
});
This works, but it's incredibly boilerplaty. What I'd really like is a way to loop through all the properties so they can be assigned to programmatically, especially without prior knowledge on the outside library/callback's part.
Is there no way to get access to a Svelte component and its properties so you can loop through them and assign them from an outside function?
Vue has a simple solution to this, because you can pass the component around, and still check and assign to its properties:
var vm = this;
ajax('/data', function(data) {
for (var key in data) {
if (vm.hasOwnProperty(key)) {
vm[key] = data[key];
}
});
});
I have seen some solutions to this, but they're all outdated - none of them work with Svelte 3.
Apologies if this has been asked before. I've spent days trying to figure this out to avoid all that extra boilerplate and the closest I could find is Access Component Object in External Callback? which does not have an answer right now.
If possible, you could put the ajax call in the parent component and have the data returned from it stored in a temporary object, that you then pass on to the component using the spread operator.
<Component { ...dataObject }></Component>
let dataObject = {};
onMount(async function() {
ajax('/data', function(data) {
dataObject = data;
});
});
You can reduce the boilerplate by using destructuring:
onMount(async function() {
ajax('/data', data => {
({ a, b, ..., z } = data);
});
});
But if you have a very large number of variables, you might be better off just putting them in an object in the first place:
let stuff;
onMount(async function() {
ajax('/data', data => {
stuff = data;
});
});
I am trying to print out of Printer. I am a little new to react and javascript. I am trying to pass the state to a then function of Third Party Code. But i am getting an error:
Cannot read property 'restaurant_name' of undefined
How can i pass state to the scope of then function of qz?
print = () => {
let { state } = this.state;
qz.websocket.connect()
.then(function() {
return qz.printers.find("BillPrinter");
}).then(function(printer) {
var config = qz.configs.create(printer);
var data = [
`${state.restaurant_name}` + '\x0A',
`${state.restaurant_address}`
]
return qz.print(config, data);
});
}
You have some unnecessary destructuring that is causing your error - this.state.state doesn't exist, yet this line:
let { state } = this.state;
Is equivalent to:
let state = this.state.state;
Remove the curly braces and it'll work fine.
let state = this.state;
Also note that state will be a reference to this.state rather than being another object.
Use arrow function to keep the function in the upper scope as #Ali Torki suggested:
.then(printer => {....})
export class ServerComponent {
servers:string[];
getString:any;
serversJSON:any;
constructor() {
}
ngOnInit() {
console.log("ngOnInit");
this.getXmlService.getData().subscribe((getString) =>
{
xml2js.parseString(getString, function (err, result) {
this.serverJSON = result; // This doesn't work
console.log(result); // This works
});
});
}
}
In this code, the indicated line does not seem to be able to access this. Console logging shows an undefined.
result gives me a correct and formatted JSON, but when I attempt to take the result variable and set it in the this.serverJSON, it throws an error Cannot set property 'serversJSON' of undefined.
I want to take the value held in result and put it in serversJSON.
How can this be achieved and why is this not available?
You are losing the context of this within your callback function.
Use a fat-arrow function (which preserves this) instead.
xml2js.parseString(getString, (err, result) => {
this.serverJSON = result;
});
Hi guys I am writing some code using the object literal pattern, I have function that returns a value:
'currentLocation': function() {
var cL = 0;
return cL;
},
I then need to update the variable 'cL' from another function like this:
teamStatus.currentLocation() = teamStatus.currentLocation() + teamStatus.scrollDistance();
This part is part of another function - however I get an error back stating: invalid assignment left-hand side
I am guessing I can not update the variable in this way, could anyone suggest a better method or point me in the right direction.
Any help would be greatly appreciated.
Going to add more code to highlight what I am trying to do:
'currentLocation': function() {
var cL = 0;
return cL;
},
'increaseTable': function() {
if (teamStatus.currentLocation() <= teamStatus.teamStatusTableHeight() ) {
teamStatus.currentLocation = teamStatus.currentLocation() + teamStatus.scrollDistance();
$("#tableTrackActual").animate({scrollTop: (teamStatus.currentLocation)});
$("#tableMembers").animate({scrollTop: (teamStatus.currentLocation) });
//console.log(teamStatus.currentLocation());
teamStatus.buttonRevealer();
}
}
As you can see increaseTable should update the value of currentLocation - help this sheds more light on what I am trying to achieve.
You're writing teamStatus.currentLocation() =, which calls the function teamStatus.currentLocation and tries to assign to the return value. That isn't valid. You want just teamStatus.currentLocation = — no function call.
The variable inside your function is completely private to that function (and any functions defined within it). If you need to create a number of functions that share a set of private variables, you can do that with a closure. For instance:
var Thing = (function() {
var thingWideData;
function getData() {
return thingWideData;
}
function setData(newData) {
thingWideData = newData;
}
return {
getData: getData,
setData: setData
};
})();
What that does is create a Thing object which has getData and setData functions available for it, which get and set the completely private thingWideData variable contained by the anonymous closure. More about this pattern here and here, although the latter of those is more about private methods than private data.
What your code produces is:
0 = 0 + <some number>
Which variable do you want to update? cL? You are declaring it in the function, you cannot assign a value to it from outside. Depending on the rest of your code, you might be better off with getters and setters:
var object = {
_cL = 0,
get currentLocation() {
return this._cL;
},
set currentLocation(value) {
this._cL = value;
}
}
then you can do:
teamStatus.currentLocation = teamStatus.currentLocation + teamStatus.scrollDistance();
Update:
Regarding IE: If currentLocation should actually be just a number, it might be sufficient to just declare it as property:
var obj = {
currentLocation: 0
}