JavaScript How to access a variable from an object passed as parameter? - javascript

I have a probably really simple problem, but I can't figure it out. I'll post some cut snippets of the code that doesn't work for some reason:
//authentication_handler.js
var new_user = server.authenticated_users.add_user(new User(world));
//user.js
function User(world) {
personBody = createPlayerBody(100, 100, 8, 8, false, true, world);
exports.TheBody = personBody;
}
//player_data_handler.js
module.exports = function(server, client) {
var theUser = server.authenticated_users.find_user(client.uuid);
if (theUser != null) {
var playerData = JSON.stringify({
x: theUser.TheBody.position.x, //this line throws the error below
y: theUser.TheBody.position.y
});
server.authenticated_users.each_other(theUser, function(user) {
server.send_id_message(user.client, 5, playerData);
});
}
};
The error I get is this:
Cannot read property 'position' of undefined
I'm still pretty new to JavaScript and I don't know why the "personBody" variable doesn't get passed all the way to the "player_data_handler.js". I've tried more approaches but none of them worked. Any help is very much appreciated!!

exports is used for exporting parts of a module. If you want to add something to your object, use this:
Instead of exports.TheBody = personBody; try this.TheBody = personBody;

Related

Why does node.js give me a parsing error even when I'm not trying to parse?

I'm somehow getting this error:
UnhandledPromiseRejectionWarning: SyntaxError: Failed to parse value of 607341305994936320votecrate, try passing a raw option to get the raw value
And I don't know why... Could anyone explain what this error means or tell me the error in my code? Thanks!
const express = require('express');
const app = express();
const path = require('path');
const port = 300;
const Database = require("#replit/database")
const db = new Database()
const Topgg = require("#top-gg/sdk")
const topggauth = process.env['topgg']
const webhook = new Topgg.Webhook(topggauth)
app.post("/dblwebhook", webhook.listener(vote => {
const user = vote.user
if (vote.type == 'test'){
console.log(vote)
}
if (vote.type){
const weekend = vote.isWeekend
function weekendcheck() {
if (weekend == "true"){
return 2
}
if (weekend == "false"){
return 1
}
}
var uservotec = (user + "votecrate")
console.log(uservotec)
db.get(uservotec).then(value => {
if (!value){
db.set(uservotec, weekendcheck())
}
if (value){
db.set(uservotec, (weekendcheck() + Number(value)))
}
});
}
}))
app.listen(port, () => console.log('App port online!'));
Thanks! Please note that the vote variable is in json format similar to this:
{
user: '607341305994936320',
type: 'test',
query: '',
bot: '981329232456192100',
isWeekend: 'false',
}
I'm inexperienced with node.js but it seems like you're trying to receive data from the database using an ID, but accidentally passing a varchar to an INT column.
If you replace db.get(uservotec) with db.get(607341305994936320) or db.get('607341305994936320') and don't get any errors, then maybe you should rethink the line var uservotec = (user + "votecrate") because it is concatenating the float/int value with the string "votecrate" resulting in "607341305994936320votecrate" which isn't a valid ID (maybe I'm wrongly assuming but I hope this helps and feel free to ask for a better explanation).
I was able to find an answer. For some reason, I needed to use JSON.stringify on the variable uservotec... Instead of the code in line 28, use this:
var uservotec = JSON.stringify(user + "votecrate")
Alternatively, you could convert the user variable to a javascript object.
var user = JSON.parse(vote.user)
Thank you for everyone's help in helping me find an answer.

More Efficient Way to Destructure with Conditional in ReactJs

I have this code in which we retrieve the data or get the data using useQuery. However, it fails anytime I attempt to call it using this method.
const { data: {getSubCategories} } = useQuery(FETCH_SUBCATEGORIES_QUERY);
It appears to throw an error stating that 'getSubCategories' is undefined, so I tried this method:
const { getSubCategories: subCategories } = { ...subCategoryData };
const { getChildCategory } = { ...data };
It works, but I think there is a better approach or more efficient way to destructure something with conditional syntaxes so it can't return undefined I guess I seem to notice it will take a few seconds before it will return data.
Would you mind commenting down below if you don't understand what I am trying to say or need more clarifications. Thank you.
It appears to throw an error stating that 'getSubCategories' is undefined
No, it's throwing an error when data is undefined. You can circumvent that by using a default:
const { data: {getSubCategories} = {} } = useQuery(FETCH_SUBCATEGORIES_QUERY);
If I've understood correctly you can try this: (safely destruct from the object)
const { data: {getSubCategories} } = useQuery(FETCH_SUBCATEGORIES_QUERY) || {};

CouchDB Document Update Handlers: Javascript

I am trying to create a generic document update handler.
I am using:
function(doc, req) {var field = req.query.field; var value =
req.query.value; var message = 'set '+field+' to '+value; doc[field] =
value; return [doc, message]; }
This works ok with simple json but not with a nested object such as
"abc":{"ax":"one", "by":"two" ...}
my curl command is:
curl -X PUT 'http://127.0.0.1:5984/db/_design/updatehandler/_update/inplace/id?field=abc.ax&value=three'
The result is a new field is created and the existing abc:{ax:one} is left
untouched.
With a simpler example:
if I have: "xyz":"five"
curl -X PUT 'http://127.0.0.1:5984/db/_design/updatehandler/_update/inplace/id?field=xyz&value=ten'
... works correctly.
I have not yet tried the generic process on "pqr":[s, t, u] yet but I guess
this may require a different design modification as well.
Ideally one wants something that works in at least the abovementioned three
cases if possible, as long as it is not too complex for it not to be worth
the effort.
Could someone possibly kindly help here or refer me to some javascript examples please.
Many thanks.
John
function (doc, req) {
function merge(nDoc,oDoc ) {
for (var f in nDoc) {
var tmpNewDoc = nDoc[f],
tmpDoc = oDoc[f];
var type = typeof(tmpNewDoc);
if (type === 'object' && tmpNewDoc.length === undefined && tmpDoc !== undefined) merge(tmpNewDoc, tmpDoc);
else oDoc[f] = tmpNewDoc;
}
}
if (!doc) {
return [null, toJSON({
error: 'not_found',
reason: 'No document were found with the specified ID or an incorrect method was used.'
})];
}
try {
var newDoc = JSON.parse(req.body);
merge(newDoc, doc);
}
catch (e) {
return [null, ToJSON({
error: 'bad_request',
reason: 'Invalid json or processing error'
})];
}
return [doc, toJSON({
doc: doc,
ok: true
})];
}"
}
Simply pass the new document to this handler. It will merge the new values to it (warning, the arrays will be overwrite). If you also want to merge array, you can either use a third party library or build your own recursive merge function.

Using idb instead of localStorage

I'm following the Progressive Web App lab from Google and it says that it's using localStorage for simplicity but that we should change it to idb.
Basically, we want to store a list of cities to display their weather information.
I tried using plain idb following the info here but I think I'm too new to this and I couldn't get any of this. Am I supposed to do:
const dbPromise = idb.open('keyval-store', 1, upgradeDB => {
upgradeDB.createObjectStore('keyval');
});
and would keyval be the name of my variable where I would use keyval.get() or keyval.set() to get and store values?
I decided to move on to the simpler idbKeyval, I'm doing:
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
idbKeyval.set(selectedCities);
};
instead of the localStorage example:
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
localStorage.selectedCities = selectedCities;
};
and
app.selectedCities = idbKeyval.keys().then(keys => console.log(keys)).catch(err => console.log('It failed!', err));
instead of the localStorage example:
app.selectedCities = localStorage.selectedCities;
But my app is not loading any data, and in the developer tools console, I get:
app.js:314 Uncaught ReferenceError: idbKeyval is not defined(…)
I'm sure I'm missing something trivial but these are my first steps with javascript and the likes, so please, any help with any of the points touched here would be greatly appreciated!
Given the error you're seeing, it looks like you've forgotten to include the idb-keyval library.
I too was going through this, and wanted it to work with localForage. Took a bit, because I'm new to it too, but here is what I used for the save and load functions which made it all work.
// TODO add saveSelectedCities function here
// Save list of cities to localStorage
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
localforage.setItem('selectedCities', selectedCities);
//localStorage.selectedCities = selectedCities;
}
localforage.getItem('selectedCities').then(function(cityList) {
app.selectedCities = cityList;
app.selectedCities.forEach(function(city) {
app.getForecast(city.key, city.label);
});
}).catch(function(err) {
app.updateForecastCard(initialWeatherForecast);
app.selectedCities = [
{key: initialWeatherForecast.key, label: initialWeatherForecast.label}
];
app.saveSelectedCities();
});

assigning variables only if undefined in javascript

I'm trying to extract two keywords from a url in this format
localhost:3000/"charactername"/"realmname"
where I want to exctract "charactername" and "realmname" and assign them to variables.
I use:
var charactername = req.url.split("/")[1];
console.log(charactername);
var realmname = req.url.split("/")[2];
console.log(realmname);
Everything works fine and dandy at first, but then it seems a request is made for a "favicon.ico", and my variables become undefined since there is a new request url. I tried solving this by encapsulating the code snippet in an if statement like this:
if(req.url !== '/favicon.ico'){
var charactername = req.url.split("/")[1];
console.log(charactername);
var realmname = req.url.split("/")[2];
console.log(realmname);
}
The console.log outputs tells me the variables are set to their correct values, it never says it is undefined so it seems to work.. However, when the next part of the code is executed:
if(charactername.length > 0){
res.writeHead(200, {'Content-Type': 'text/html'});
renderer.view("header", {}, res);
//get json from battle.net
var characterProfile = new Profile(charactername, realmname);
//on "end"
characterProfile.on("end", function(profileJSON){
//Show profile
//Store values we need
var values = {
avatarURL: profileJSON.thumbnail,
charactername: profileJSON.name,
realmname: profileJSON.realm,
level: profileJSON.level
}
//Simple response
renderer.view("profile", values, res);
renderer.view("footer", {}, res);
res.end();
});
I get an error saying cannot read property length of undefined. So it seems the variables become undefined somehow anyway. Anyone got a clue on how to solve this?
if(x === undefined){
//do something
}
This checks if the variable is undefined, however I suggest you check what is causing the error in the first place.
if(charactername && charactername.length > 0){
...

Categories

Resources