103

I'm currently developing a desktop application with Node-webkit. During that process I need to get some data from a local MySQL-database.

The querying works fine, but I can't figure out how to access the results. I store all of them in an array that is then passed to a function. In the console they look like this:

RowDataPacket {user_id: 101, ActionsPerformed: 20}
RowDataPacket {user_id: 102, ActionsPerformed: 110}
RowDataPacket {user_id: 104, ActionsPerformed: 3}

And here is the query structure:

var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
    if (err)
        alert("...");
    else {
        for (var i of rows) 
            ret.push(i);
    }
    doStuffwithTheResult(ret);
}

How do I retrieve this in the doStuffwithTheResult function? The values are more important, but if I could get the keys as well that would be great.

ucMedia
  • 4,105
  • 4
  • 38
  • 46
paK0
  • 2,548
  • 4
  • 13
  • 9

17 Answers17

130

Turns out they are normal objects and you can access them through user_id.

RowDataPacket is actually the name of the constructor function that creates an object, it would look like this new RowDataPacket(user_id, ...). You can check by accessing its name [0].constructor.name

If the result is an array, you would have to use [0].user_id.

Caleb Taylor
  • 2,670
  • 2
  • 21
  • 31
paK0
  • 2,548
  • 4
  • 13
  • 9
  • 1
    Thanks for coming back to answer your own question. I was doing `RowDataPacket.user_id` and it was undefined. This saved me some headache :) – Damodar Bashyal Mar 02 '17 at 00:57
  • 4
    If the results are in an array, then you need to access them as results[0].user_id – zegulas Nov 08 '17 at 04:09
  • just one pressing question i have, how is console.log logging out a non uniform javascript object? what's going on under the hood? – Ayyash Aug 17 '20 at 13:12
41

With Object.prototype approach, JSON.parse(JSON.stringify(rows)) returns object, extract values with Object.values()

let result = Object.values(JSON.parse(JSON.stringify(rows)));

Usage:

result.forEach((v) => console.log(v));
FranSanchis
  • 1,455
  • 14
  • 15
31

I also met the same problem recently, when I use waterline in express project for complex queries ,use the SQL statement to query.

this is my solution: first transform the return value(RowDataPacket object) into string, and then convert this string into the json object.

The following is code :

//select all user (查询全部用户)
find: function(req, res, next){
    console.log("i am in user find list");
    var sql="select * from tb_user";

    req.models.tb_user.query(sql,function(err, results) {
        console.log('>> results: ', results );
        var string=JSON.stringify(results);
        console.log('>> string: ', string );
        var json =  JSON.parse(string);
        console.log('>> json: ', json);
        console.log('>> user.name: ', json[0].name);
        req.list = json;
        next();
    });
}

The following is console:

    >> results:  [ RowDataPacket {
    user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
    name: 'wuwanyu',
    psw: '123',
    school: 'Northeastern university',                                                                                                                                           
    major: 'Communication engineering',                                                                                                                                            
    points: '10',
    datems: '1450514441486',
    createdAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),                                                                                                  
    updatedAt: Sat Dec 19 2015 16:42:31 GMT+0800 (中国标准时间),                                                                                                  
    ID: 3,
    phone: 2147483647 } ]
>> string:  [{"user_id":"2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5","name":"wuwanyu","psw":"123","school":"Northeastern university","major":"Communication engineering","points":"10","datems":"1450514
441486","createdAt":"2015-12-19T08:42:31.000Z","updatedAt":"2015-12-19T08:42:31.000Z","ID":3,"phone":2147483647}]
>> json:  [ { user_id: '2fc48bd0-a62c-11e5-9a32-a31e4e4cd6a5',
    name: 'wuwanyu',
    psw: '123',
    school: 'Northeastern university',                                                                                                                                           
    major: 'Communication engineering',                                                                                                                                            
    points: '10',
    datems: '1450514441486',
    createdAt: '2015-12-19T08:42:31.000Z',
    updatedAt: '2015-12-19T08:42:31.000Z',
    ID: 3,
    phone: 2147483647 } ]
>> user.name:  wuwanyu
zero323
  • 322,348
  • 103
  • 959
  • 935
user5545457
  • 311
  • 3
  • 2
  • 11
    i ended up using `JSON.parse(JSON.stringify(results))` – RozzA Sep 22 '16 at 01:30
  • I wanted the results on my frontend and all I had to do was `res.send(JSON.stringify(results))`, no `JSON.parse` needed. it got parsed automatically on the frontend. thanks for pointing me in the right direction! – Noam Hacker Feb 19 '17 at 04:15
  • NOTE: the answer in the comments from RozzA will do the trick in most situations, thanks RozzA, – WebDev-SysAdmin Dec 26 '21 at 16:24
  • For those considering JSON.parse/JSON.stringify: It may be pertinent to use structuredClone if you're using Babel/a polyfill: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone – Max Jan 10 '22 at 23:39
20

Hi try this 100% works:

results=JSON.parse(JSON.stringify(results))
doStuffwithTheResult(results); 
Bùi Đức Khánh
  • 3,975
  • 6
  • 27
  • 43
Durai Vinoth
  • 327
  • 2
  • 5
  • It may be pertinent to use structuredClone if you're using Babel/a polyfill: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone – Max Jan 10 '22 at 23:38
  • need to see if this messes up datetime objects, but so far strings ints and floats all hold up. – WEBjuju Feb 22 '22 at 19:14
15

You can copy all enumerable own properties of an object to a new one by Object.assign(target, ...sources):

trivial_object = Object.assign({}, non_trivial_object);

so in your scenario, it should be enough to change

ret.push(i);

to

ret.push(Object.assign({}, i));
Jan Šourek
  • 623
  • 6
  • 11
6

you try the code which gives JSON without rowdatapacket:

var ret = [];
conn.query(SQLquery, function(err, rows, fields) {
    if (err)
        alert("...");
    else {
        ret = JSON.stringify(rows);
    }
    doStuffwithTheResult(ret);
}
Kumaresan Perumal
  • 1,926
  • 2
  • 29
  • 35
4

going off of jan's answer of shallow-copying the object, another clean implementation using map function,

High level of what this solution does: iterate through all the rows and copy the rows as valid js objects.

// function  will be used on every row returned by the query
const objectifyRawPacket = row => ({...row});

// iterate over all items and convert the raw packet row -> js object
const convertedResponse = results.map(objectifyRawPacket);

We leveraged the array map function: it will go over every item in the array, use the item as input to the function, and insert the output of the function into the array you're assigning.

more specifically on the objectifyRawPacket function: each time it's called its seeing the "{ RawDataPacket }" from the source array. These objects act a lot like normal objects - the "..." (spread) operator copies items from the array after the periods - essentially copying the items into the object it's being called in.

The parens around the spread operator on the function are necessary to implicitly return an object from an arrow function.

Julian
  • 550
  • 1
  • 4
  • 16
  • 3
    I tried your solution and it works faster (ran comparison with multiple no. of records of multiple record lengths) than JSON stringifiying and parsing the stringified JSON. I tried with `for loop` instead of `map`, and it is little faster. `Object.assign()` is faster of all approaches (solution by jan). comparisons : https://gist.github.com/jastisriradheshyam/3e69aeda1b169345e3834b7b8f891560#gistcomment-3049253 – Jasti Sri Radhe Shyam Oct 08 '19 at 15:33
4

Solution

Just do: JSON.stringify(results)

Predrag Davidovic
  • 1,411
  • 1
  • 17
  • 20
3

I found an easy way

Object.prototype.parseSqlResult = function () {
    return JSON.parse(JSON.stringify(this[0]))
}

At db layer do the parsing as

let users= await util.knex.raw('select * from user')
    return users.parseSqlResult()

This will return elements as normal JSON array.

M14
  • 1,780
  • 2
  • 14
  • 31
3

If anybody needs to retrive specific RowDataPacket object from multiple queries, here it is.

Before you start

Important: Ensure you enable multipleStatements in your mysql connection like so:

// Connection to MySQL
var db = mysql.createConnection({
  host:     'localhost',
  user:     'root',
  password: '123',
  database: 'TEST',
  multipleStatements: true
});

Multiple Queries

Let's say we have multiple queries running:

  // All Queries are here
  const lastCheckedQuery = `
    -- Query 1
    SELECT * FROM table1
    ;

    -- Query 2
    SELECT * FROM table2;
    `
    ;

  // Run the query
  db.query(lastCheckedQuery, (error, result) => {
    if(error) {
      // Show error
      return res.status(500).send("Unexpected database error");
    }

If we console.log(result) you'll get such output:

[
  [
    RowDataPacket {
      id: 1,
      ColumnFromTable1: 'a',
    }
  ],
  [
    RowDataPacket {
      id: 1,
      ColumnFromTable2: 'b',
    }
  ]
]

Both results show for both tables.

Here is where basic Javascript array's come in place https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

To get data from table1 and column named ColumnFromTable1 we do

result[0][0].ColumnFromTable1 // Notice the double [0]

which gives us result of a.

Eduards
  • 1,734
  • 2
  • 12
  • 37
1
db.query('select * from login',(err, results, fields)=>{
    if(err){
        console.log('error in fetching data')
    }
    var string=JSON.stringify(results);
    console.log(string);
    var json =  JSON.parse(string);
   // to get one value here is the option
    console.log(json[0].name);
})
rahul kumar
  • 135
  • 6
1
conn.query(sql, (err,res,fields) => {
    let rawData = res;
    let dataNormalized = {...rawData[0]};
})

//Object Destructuring

This worked for me hope it helps you.

I think it is simplest way to copy object.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Dragan994
  • 9
  • 3
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 04 '22 at 06:26
  • wow, i thought all the answers were super old. Anyways just to add to ^ i had to add a Array check to make typescript happy `if (Array.isArray(rows)) return rows.map(x => ({ ...x })); ` – Namrata Apr 28 '22 at 16:09
0

Simpler way:

.then( resp=> {
  let resultFromDb= Object.values(resp)[0]
  console.log(resultFromDb)
}

In my example I received an object in response. When I use Object.values I have the value of the property as a response, however it comes inside an array, using [0] access the first index of this array, now i have the value to use it where I need it.

Max
  • 27
  • 5
0

I had this problem when trying to consume a value returned from a stored procedure.

console.log(result[0]);

would output "[ RowDataPacket { datetime: '2019-11-15 16:37:05' } ]".

I found that

console.log(results[0][0].datetime);

Gave me the value I wanted.

  • I was having the same issue with mySQL store procedure and this worked as expected for me. I was reluctant to try this because it was down, weird as it perfectly for me while the accepted solution did not. Thank you! – user752746 Jan 30 '20 at 01:28
0

I had a similar problem and the solution was as follows:

const results = pool.query('sql sentence',[params]);

console.log((results[0])[0].name);
  • 2
    Hello, and welcome to stack overflow. Thanks for posting this, but all posts to stack overflow are requested to be in English. See [here](https://meta.stackoverflow.com/a/297680/) for details. Please either [edit] the post and translate, or [delete](https://meta.stackexchange.com/q/25088) this post. – dbc May 21 '21 at 22:50
  • Google [says](https://translate.google.com/?sl=auto&tl=en&text=Tuve%20un%20problema%20parecido%20y%20la%20soluci%C3%B3n%20fue%20la%20siguiente%3A&op=translate) the translation is *I had a similar problem and the solution was as follows:*. – dbc May 21 '21 at 22:51
  • This actually worked for me when moving from and working recent JS to problematic TS project port. This answer gave me the hint that instead of var affectedRows = r[0].affectedRows; that I should do var affectedRows = r[0][0].affectedRows to access the underlying mutated RowDataPacket – pythlang Feb 04 '23 at 16:42
0

How to ACCESS what you get back from the database, this works for me:

async function getPageId(pageSlug){

let sql_update = 'SELECT id FROM pages WHERE pageSlug = ?';
let arrValues = [
    pageSlug
];

let result = await mydb.query(sql_update, arrValues);

let r = JSON.parse(JSON.stringify(result));
if(r?.length){
    return r[0].id;
}else{
    return false;
}

}

WebDev-SysAdmin
  • 269
  • 4
  • 12
-1

I really don't see what is the big deal with this I mean look if a run my sp which is CALL ps_get_roles();. Yes I get back an ugly ass response from DB and stuff. Which is this one:


[
  [
    RowDataPacket {
      id: 1,
      role: 'Admin',
      created_at: '2019-12-19 16:03:46'
    },
    RowDataPacket {
      id: 2,
      role: 'Recruiter',
      created_at: '2019-12-19 16:03:46'
    },
    RowDataPacket {
      id: 3,
      role: 'Regular',
      created_at: '2019-12-19 16:03:46'
    }
  ],
  OkPacket {
    fieldCount: 0,
    affectedRows: 0,
    insertId: 0,
    serverStatus: 35,
    warningCount: 0,
    message: '',
    protocol41: true,
    changedRows: 0
  }
]

it is an array that kind of look like this:


rows[0] = [
    RowDataPacket {/* them table rows*/ },
    RowDataPacket { },
    RowDataPacket { }
];

rows[1] = OkPacket {
   /* them props */
}

but if I do an http response to index [0] of rows at the client I get:

[
  {"id":1,"role":"Admin","created_at":"2019-12-19 16:03:46"}, 
  {"id":2,"role":"Recruiter","created_at":"2019-12-19 16:03:46"},
  {"id":3,"role":"Regular","created_at":"2019-12-19 16:03:46"}
]

and I didnt have to do none of yow things

rows[0].map(row => {
   return console.log("row: ", {...row});
});

the output gets some like this:

row:  { id: 1, role: 'Admin', created_at: '2019-12-19 16:03:46' }
row:  { id: 2, role: 'Recruiter', created_at: '2019-12-19 16:03:46' }
row:  { id: 3, role: 'Regular', created_at: '2019-12-19 16:03:46' }

So you all is tripping for no reason. Or it also could be the fact that I'm running store procedures instead of regular querys, the response from query and sp is not the same.

Ernesto
  • 3,944
  • 1
  • 14
  • 29