I've been working on a project with nodejs and pg-promise. Couldn't quite figure out how to implement parameterized query. Here how my code looks like:
// let's say we have an array
var hex = new Array;
hex = [[0, 1, 2, 'string1', 3, 'string2'],[4, 5, 6, 'string3', 7, 'string4']];
//lets assume db is initialized with correct parameters and we have a for loop
for (var i=0; i<hex.length; i++){
db.tx(t => {
return t.batch([
t.none('INSERT INTO x (lat, long, name) VALUES ($1[$2][0], $1[$2][1],
$1[$2][4];)',[hex,i]),
t.none('DELETE FROM x WHERE name='y'; ')];
)}
.then(data => {})
.catch(error => {
console.log('ERROR:', error);
});
)
}
My guess is that I'm not coding in right syntax especially in
t.none('INSERT INTO x (lat, long, name) VALUES ($1[$2][0], $1[$2][1], $1[$2][4];)',[hex,i]
I've read about the difference between passing arrays and parameters-functions in Vitaly's documentation. But couldn't merge them together since I'm guessing I need them both.
What am I doing wrong here?
EDIT: btw I'm getting syntax error near '['.
Thanks in advance!
Related
I am new to node-postgres and I want to insert a row in a table using node-postgres, where one column value is an array of strings and one an array of integers.
Earlier I used to use sequelize and now I am not using any ORMS, want to use the native library for postgres in Node.
let names =['abc', 'qwe', 'aaa'];
let type = [2, 3, 4, 5];
let query = 'INSERT INTO sample(names, type) VALUES ($1, $2)' ;
db.query(query, [names, type], (err, res) => {
if (err) {
return (err)
}
return res.send(res.rows[0])
})
I am thrown an error invalid syntax near "["
I want to get the size of the array in my DB so I can loop through it, so I created a field called Size in my DB. I want to store the value of this field in a variable so I know how many times I need to loop through the array. I am able to print out the whole document, but I cannot single out the Size value.
Here is my DB document:
_id:ObjectId("5c02492d1c9d440000498a9b")
Names:Array
Size:5
Now, this is my code that I am trying to extract the number 5 from the size field.
var cursor = db.collection('Room').find('Size');
cursor.forEach(function (err, num) {
if(err) {
return console.log(err);
}
console.log(num);
});
This is what console.log(num) prints:
{ _id: 5c02492d1c9d440000498a9b,
Names:
[ 'TjAa0wOe5k4',
'Sz_YPczxzZc',
'mM5_T-F1Yn4',
'En6TUJJWwww',
'5T_CqqjOPDc' ],
Size: 5 }
Any ideas/help?
For anyone who is wondering, I figured it out. It turns out that turning the result into an array and then calling numArr[0].Size works. Here is the code for anyone curious:
var length;
db.collection('Room').find({'Size': Object}).toArray((err, numArr) => {
if(err) {
return console.log(err);
}
length = numArr[0].Size
return length;
});
Update:
OP fixed it by converting the cursor to an array using .toArray() method and then referencing the property like numArr[0].Size.
You can access the Size property like this:
var size = num.Size;
Have you tried it this way?
I've no habit to use semicolon ; in javascript code. This is my API but this is not working. Here response showing 500 Internal Server Error
router.post('/addRows', function (req, res) {
const saveData = []
[1,2,3,4,5,6,7,8,9,10].map((i) => {
console.log(i)
saveData.push(i)
if (saveData.length === 10) {
res.status(200).json({'data': saveData});
}
})
})
but If I add semicolon ; after 2nd line then this code is working. Here response showing 200 OK
router.post('/addRows', function (req, res) {
const saveData = [];
[1,2,3,4,5,6,7,8,9,10].map((i) => {
console.log(i)
saveData.push(i)
if (saveData.length === 10) {
res.status(200).json({'data': saveData});
}
})
})
What is issue. Please describe
You are experiencing one of the issues with automatic semicolon insertion, the feature of JavaScript that allows semicolons to be "optional".
In your case, when you miss out the semicolon after the array assignment, the array literal on the following line is being interpreted as a reference to an element within the array, which is of course undefined. You can read your code as:
router.post('/addRows', function (req, res) {
const saveData = [][1,2,3,4,5,6,7,8,9,10].map((i) => {
console.log(i)
saveData.push(i)
if (saveData.length === 10) {
res.status(200).json({'data': saveData});
}
})
})
That may not look valid but it is - the second array literal is being parsed as a property lookup containing an expression with comma ("grouping") operators. The comma operator returns its final operand, so you can simplify the above:
router.post('/addRows', function (req, res) {
const saveData = [][10].map((i) => {
console.log(i)
saveData.push(i)
if (saveData.length === 10) {
res.status(200).json({'data': saveData});
}
})
})
When you add the semicolon you remove the ambiguity and cause the second array literal to be parsed as an array literal rather than a property accessor.
If the ‘;’ is missed, your code will look like:
const saveData = [][1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(...)
it is going to access element from the empty array [], this code is equals to below:
const saveData = [][10].map(...)
obviously the 10th index of an empty array is undefined, so you will get TypeError: Cannot read property 'map' of undefined
Update:
Here are posts on this topic:
Why I Prefer To Use Semicolon In JavaScript
An Open Letter to JavaScript Leaders Regarding No Semicolons
I am building a simple API that also deal with geometries (store into postGIS).
I am using knex-postgis to access the ST_ spatial functions in postGIS with knex.
I have used this example to insert a point and it work when its hard coded.
But my lack of experience is leave me hanging, how can I make the query dynamic? I want to create a form with input for x and y value and send it to the ST_geomFromText function to save it to the geom type in the db.
Is this when you would use parameters? Could someone point me in the right direction?
// insert a point
const sql1 = db.insert({
id: 1,
geom: st.geomFromText('Point(0 0)', 4326)
}).into('points').toString();
console.log(sql1);
// insert into "points" ("geom", "id") values
(ST_geomFromText('Point(0 0)'), '1')
So far I have tried
router.post('/', (req, res, next) => {
queries.create(req.body).then(poi => {
res.json(poi[0]);
});
});
Insert query
create(poi) {
const sql = db.insert(poi).returning('*').into('poi');
return sql;
},
In Postman I am sending this in its body
{
"place": "test",
"comments": "new",
"numbers": 6,
"geom": "st.geomFromText('Point(-71.064544 44.28787)', 4326)"
}
But get an error "Unhandled rejection error: parse error - invalid geometry"
The hard coded object looks the same and is work fine.
I have a feeling that I am using the st.geomFromText wrong, but i dont I am not sure?
This is what i get if i console.log returned query
insert into "poi" ("comments", "geom", "numbers", "place") values ('new', 'st.geomFromText(''Point(-71.064544 44.28787)'', 4326)', 6, 'test')
(see how it does not change st.geom.. to st_geom..? Also the quotation marks around the ST function and the Point object is not right)
This string work when I run it in pgAdmin
insert into "poi" ("comments", "geom", "numbers", "place") values ('new', st_GeomFromText('Point(-71.064544 44.28787)', 4326), 6, 'test')
EDIT:
I console.log the hardcoded version too. It does no appear to add the extra '' on the geometry value
insert into "poi" ("geom") values (ST_geomFromText('Point(-71.064544 44.28787)', 4326))
Any advice?
You pass coordinates from postman as string value in JSON object
"geom": "st.geomFromText('Point(-71.064544 44.28787)', 4326)"
And expect your code to transform it into a function call
st.geomFromText('Point(-71.064544 44.28787)', 4326)
What knex does in this case. It takes your string and convert it as it is string field (here you get a single quote ' replacement with double '' for Postgres to escape it).
What you can do. Pass your geometry to your API like this
"geom": "Point(-71.064544 44.28787)"
And in your route handler
create(poi) {
const sql = db.insert({
place: poi.place,
comments: poi.comments,
numbers: poi.numbers,
geom: st.geomFromText(poi.geom, 4326)
}).returning('*').into('poi');
return sql;
},
The problem is that I have an array which maybe like [1,2,3], and the content is video._id I don't want to get.
var used = [1, 2 , 3];
Video.findOne({'videoClass': watchRecord[i]}).ne('_id', used).sort('-viewTimes').exec(function (err, doc) {
if (err){
console.log(err);
return;
}
temp.push(doc);
}
});
I find ne or {$ne:}, but it's not work. How to query data that except items in array I don't want?
$ne operator is not supposed to be used with an Array, I think you need to use $nin.
Related links:
Mongoose Docs
MongoDB Docs