Brief Explanation: I have fetched result in variable res using **js**.
Result of res on console is shown below.
see here
Requirement: I want to get the value of res in angular variable. I have declared
resarry = [];
When i do
this.resarry = res;
console.log(this.resaary);
Error coming - Cannot set property of 'resarray` undefined.
console.log(results); // no problem in this line
console.log(this.resarry); // giving error
export class HomePage {
resarry = [];
constructor(){
var connection = new JsStore.Instance();
var dbName = 'Demo';
connection.openDb(dbName);
connection.select({
from: Test1,
}).then(function(res) {
// results will be array of objects
console.log(res,'results');
this.resarry = results;
console.log(results); // no problem in this line
console.log(this.resarry); // giving error
}).catch(function(err) {
console.log(err, 'error');
alert(err.message);
});
}
}
Change:
connection.select({
from: Test1,
}).then(function(res) {
// ...
});
to:
connection.select({
from: Test1,
}).then(res => {
// ...
});
Basically, function() { ... } can't access this from the outer scope, while arrow functions can. A more in-depth explanation can be found here.
Also, arrow functions' docs.
resarry:number[] = new Array();
will initialize an empty array which is not undefined.
you can set the type where your result is expected to be.
Because, the "this" meant to be the current function object. So the "this", you have used in the constructor is not the actual component
Use Arrow function or
constructor(){
var connection = new JsStore.Instance();
var dbName = 'Demo';
connection.openDb(dbName);
var $this = this;
connection.select({
from: Test1,
}).then(function(res) {
// results will be array of objects
console.log(res,'results');
$this.resarry = results;
console.log(results); // no problem in this line
console.log($this.resarry); // giving error
}).catch(function(err) {
console.log(err, 'error');
alert(err.message);
});
}
connection.select({
from: Test1,
}).then(function(res) { // results will be array of objects
console.log(res,'results');
this.resarry = results; // perhaps like that => this.resarry = res
console.log(results); // i think, you should have an error on this line because **results** isn't a variable but a string in your console
console.log(this.resarry); // giving error
})
User arrow functions as well as typescript types to validate things before assigning
export class HomePage {
resarry: any[] = []; //--> resarry: any[] -> used to set the type as array
constructor() {
let connection = new JsStore.Instance(); //-> use Let insted of Var
let dbName = 'Demo';
connection.openDb(dbName);
connection.select({
from: "Test1",
}).then(res => {
console.log(res);
if (res)
if (res.length > 0){
this.resarry = res;
console.log(this.resarry);
console.log("connection Successful with array objects");
}else{
console.log("connection Successful without array objects");
}
}), err => {
console.log("connection error");
};
}
}
Related
I'm learning to build APIs with Express. I figured that every time I have to send a successful JSON response, I have to duplicate most of the code. So I tried to put it in a function like so in one of my controller modules:
const successResponse = (res, statusCode, obj, coll = false) => {
const successObj = { status: "success" };
if (coll) successObj.results = obj.length;
successObj.data = { obj };
return res.status(statusCode).json(successObj);
};
exports.getPlayer = asyncErrorHandler(async (req, res, next) => {
const player = await Player.findById(req.params.id);
if (!player) return next(new AppError("Player not found", 404));
successResponse(res, 200, player);
}
The problem is in the line successObj.data = { obj } where I want the result to be the name of the argument that is passed as key and the object as value(s). The result I currently get is:
{
"status": "success",
"data": {
"obj": { // I want this key to be "player" here
"name": "Sal"
}
}
}
As the comment says I would like the key to be the string that I passed as the object name. I can do it by passing another argument as a string but it will always be the same as the object name that I pass. Is there a better way to do this?
You pass the name to the successResponse like this:
exports.getPlayer = asyncErrorHandler(async (req, res, next) => {
const player = await Player.findById(req.params.id);
if (!player) return next(new AppError("Player not found", 404));
successResponse(res, 200, {objName: "player" , value: player);
}
And then change your successResponse like this:
// Set a suitable default value for objName (e.g. "obj") if you don't want to send it every time
const successResponse = (res, statusCode, {objName = "obj", value}, coll = false) => {
const successObj = { status: "success" };
if (coll) successObj.results = obj.length;
successObj.data = { [objName]: {value}}; // { player : { name : "Sal"} }
return res.status(statusCode).json(successObj);
};
EDIT 1 => NOTE: You can't access the name of the variable that passed to a function unless the name string was explicitly passed. Because only the value that a variable held is passed along not the name. This why you have to pass it the name. The solution I gave would not need another argument to function but it will need another key/value inside the object passed.
**EDIT 2 => ** Even more cleaner solution
exports.getPlayer = asyncErrorHandler(async (req, res, next) => {
const player = await Player.findById(req.params.id);
if (!player) return next(new AppError("Player not found", 404));
successResponse(res, 200, {player}); //Same as {"player" : player}
}
And then change your successResponse like this:
const successResponse = (res, statusCode, obj, coll = false) => {
const successObj = { status: "success" };
if (coll) successObj.results = obj.length;
successObj.data = { ...obj };
return res.status(statusCode).json(successObj);
};
You are getting a single object and trying to use that as key and value. You can try something like this:
Suppose your obj is
var obj = { player: {
"name": "Sal"
}}
then while pushing to data you can follow these steps:
var selectedKey = Object.keys(obj)[0]; // assuming you will have a single key, if you have multiple then select based on the index
var selectedKeyData = Object.values(obj)[0];
var data = {};
data[selectedKey] = selectedKeyData;
Now, your data will have desired result.
I need to be able to pull out a specific value from an array to be able to use it in an IF statement to filter out data within a SQL. What my goal is to be able to do is to create something like this
if(obj !== undefined){ //do something} else { //do something else }
The reason why I need to do this is to know if there is an entry or not within the SQL and this was the only what I could think of doing that. To check if it returns any values when searching for it.
The code:
con.query("SELECT * FROM whitelisttest WHERE (identifier) = (?)", [messageArray[1]], function (err, result) {
if (err) throw err;
var person = JSON.stringify(result);
obj = JSON.parse(person);
test = obj.whitelisted;
console.log(result);
console.log(obj);
console.log(person);
console.log(test);
Console log result:
[ RowDataPacket { identifier: 'etanol', whitelisted: 3 } ]
[ { identifier: 'etanol', whitelisted: 3 } ]
[{"identifier":"etanol","whitelisted":3}]
undefined
The expected result is for the output that is currently undefined and that is called test in the code to be 3, and for the result to be etanol if I did.
test = obj.identifier
console.log(test)
EDIT:
Solution that helped me (missed the [0] when trying to do obj.whitelisted when it was supposed to be obj[0].whitelisted)
con.query("SELECT * FROM whitelisttest WHERE (identifier) = (?)", [messageArray[1]], function (err, result) {
if (err) throw err;
var person = JSON.stringify(result);
obj = JSON.parse(person);
console.log(obj[0].whitelited)
this is an array console.log(Array.isArray(result) ) // => true
so your complete answer shoud be :
con.query( "SELECT * FROM whitelisttest WHERE (identifier) = (?)"
, [messageArray[1]]
, function (err, result)
{
if (err) throw err;
console.log(result[0].whitelisted)
//...
no need to use JSON.stringify and then JSON.parse
var obj = [ { identifier: 'etanol', whitelisted: 3 } ];
console.log(' obj[0].whitelisted => ', obj[0].whitelisted); // => 3
var ref = 'whitelisted';
console.log(' obj[0][ref] => ', obj[0][ref]); // => 3
console.log(' obj[0]["whiteliste"] => ', obj[0]['whitelisted']); // => 3
Because it's an array, you need to access the property whitelisted of the first element:
var person = [{
"identifier": "etanol",
"whitelisted": 3
}]
console.log(person[0].whitelisted);
I have the app on node.js with connecting to firebase. I need to update the data correctly.
How to call the function getOrSetUserTrackDay(day) in a promise to get a good value, but not undefined?
let userData = [];
let userID = req.params.userID;
let today = req.params.today;
let yesterday = req.params.yesterday;
db.collection('users').doc(userID).get()
.then((userDataFromDB) => {
if (!userDataFromDB.exists) {
res.status(404).send('User not found');
}
else {
function getOrSetUserTrackDay(day) {
let userTrackRef = db.collection('history').doc('daily').collection(day).doc(userID);
userTrackRef.get()
.then(userTrackData => {
if (userTrackData.exists) {
return userTrackData.data(); // good
}
else {
let userNewData = {
username: userDataFromDB.data().username,
photoUrl: userDataFromDB.data().photoUrl
};
userTrackRef.update(userNewData);
return userNewData; // good
}
})
}
userData = {
user: userDataFromDB.data(),
today: getOrSetUserTrackDay(today), // undefined
yesterday: getOrSetUserTrackDay(yesterday) // undefined
};
res.json(userData);
}
})
.catch((err) => {
console.log(err);
res.status(404).send(err);
});
well getOrSetUserTrackDay has no return statement, hence it returns undefined - but, since it contains asynchronous code, you'll never be able to use it synchronously
So, you can do the following
let userData = [];
let userID = req.params.userID;
let today = req.params.today;
let yesterday = req.params.yesterday;
db.collection('users').doc(userID).get()
.then((userDataFromDB) => {
if (!userDataFromDB.exists) {
res.status(404).send('User not found');
}
else {
let getOrSetUserTrackDay = day => {
let userTrackRef = db.collection('history').doc('daily').collection(day).doc(userID);
return userTrackRef.get()
.then(userTrackData => {
if (userTrackData.exists) {
return userTrackData.data(); // good
} else {
let userNewData = {
username: userDataFromDB.data().username,
photoUrl: userDataFromDB.data().photoUrl
};
userTrackRef.update(userNewData);
return userNewData; // good
}
});
};
Promise.all([getOrSetUserTrackDay(today), getOrSetUserTrackDay(yesterday)])
.then(([today, yesterday]) => res.json({
user: userDataFromDB.data(),
today,
yesterday
}));
}
}).catch((err) => {
console.log(err);
res.status(404).send(err);
});
Note: changed getOrSetUserTrackDay from a function declaration to a function expression (in this case, an arrow function for no particular reason) - because Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.
I am facing a difficulty in obtaining the property value from a javascript class object.
The following is the class files and how I try to get its property value:
1: I defined a class named School in classes.js
export class School{
constructor()
{
this.schools = []; //to store schools returned from backend
}
//used to get all schools
getall()
{
axios.get('/api/schools')
.then(response =>{
this.schools = response.data;
console.error('School length: ' + this.schools.length);
this.ok = true;
//add origin data property
for(let i = 0; i < this.schools.length; i++)
{
this.schools[i]['orgValue'] = new tagChange();
}
})
.
catch(error => {
this.ok = false;
this.error = error.status;
this.schools = [];
});
return this.schools;
} //getall
}
2: I import this School class to another js file
//import School class
import {tagChange, School} from './classes.js';
export default {
components: {
modalAddSchool,
},
data() {
return {
schools: [], // my schools in
mySchoolObj: new School(), //create a School object
}
},
methods: {
getAllSchools()
{
//after this call, mySchoolObj's schools property indeed contain 8 elements in array format,
//However, this.schools can not be assigned successfully, so unexplainable
this.schools = this.mySchoolObj.getall();
//print zero element
console.log(this.mySchoolObj.schools);
//print zero element
console.log(this.schools)
}
},
3: after call getAllSchools() method, the mySchoolObj.schools indeed contain 8 school elements but this.schools cannot be assigned successfully, neither the following two console.log call can only print zero length
4: I really want to know how to return all the mySchoolObj.schools to this.schools, and how to get/visit its other property value?
axios.get is asynchronous, it means that when you return this.schools;, the ajax call is not finished yet so you return an empty array [].
More informations here:
Synchronous and asynchronous requests
You can return the promise given by axios or use a callback, like that:
//used to get all schools
getall(callback) { // take a callback function
axios.get('/api/schools')
.then(response =>{
this.schools = response.data;
console.error('School length: ' + this.schools.length);
this.ok = true;
//add origin data property
for (let i = 0; i < this.schools.length; i++) {
this.schools[i]['orgValue'] = new tagChange();
}
if (typeof callback === 'function') {
callback(this.schools, null); // call the callback with data and null (null because there is no error)
}
})
.catch(error => {
this.ok = false;
this.error = error.status;
this.schools = [];
if (typeof callback === 'function') {
callback(null, error.status); // call the callback with null data and the error status
}
});
return this.schools;
}
Then you can use your method like that:
methods: {
getAllSchools() {
this.mySchoolObj.getall((data, error) => {
if (error) {
return console.log(error);
}
this.schools = data;
console.log(this.schools);
});
}
},
(this code isn't tested, it may contain bugs)
Now I have this code to create sitemap.xml when I run /sitemap.xml
database = firebase.database();
var ref = database.ref('urls');
ref.on('value', gotData, errData);
function errData(err){
console.log('Error!');
console.log(err);
}
function gotData(data){
result = data.val()
return Object.keys(result)
.filter(key => result[key].last_res > 5)
.map(key => ({url: '/' + result[key].url_site + '/'}));
var urls = gotData(data);
}
when i try running console.log(urls) in gotData(data) function, it returns as
{ salmon:
{ count: 1,
last_res: 10,
url_site: 'salmon' },
'salmon-food':
{ count: 1,
last_res: 601,
url_site: 'salmon-food' } }
I need to return 'urls' in gotData(data) to create sitemap.xml.
var sitemap = sm.createSitemap({
hostname: 'xxx.com',
cacheTime: 600000,
urls: urls
});
app.get('/sitemap.xml', function(req, res) {
sitemap.toXML( function (err, xml) {
if (err) {
return res.status(500).end();
}
res.header('Content-Type', 'application/xml');
res.send( xml );
});
});
}
But now its error on var = sitemap as
urls: urls -> urls is not defined
So how can I fix it?
You are assigning and returning in one line. You either need to define the variable and then return it, or just return the result directly without assigning to a variable.
return Object.keys(result)
.filter(key => result[key].last_res > 5)
.map(key => ({url: '/' + result[key].url_site + '/'}));
It's also not clear where you are defining the urls variable that you are passing in the sm.createSitemap() function. Make sure that it exists within the scope that you are defining var sitemap.
You are likely missing a line similar to the following:
var urls = gotData(data);