Apollo query array within an array - ionic-framework

Return from Server
In Apollo I can query down about two levels and then I get "returns undefined". I can get down to "project" on line 7, But I cannot get "Checklists" on line 12. Any help would be greatly appreciated.
updateNotication(){
this.apollo
.watchQuery({
query: gql`
query
{
project
(id:[2272],accesstoken:"val")
{
ID,
Title,
Checklists
{
ID,
Name,
DateDue
}
}
}
`,
})
.valueChanges.subscribe((result: ApolloQueryResult<any> ) => {
console.log('data', result.data); // returns data Object
console.log('project', result.data.project); // returns project array
console.log('Checklists', result.data.project.Checklists); // returns undefined
});
}

result.data.project is an Array. If you want to get the property of one of the arrays items, you need to do something like:
result.data.project[0].Checklists

Related

MongoDB query returns empty array for one thing but not another

I'm working on a basic app that returns a list of books based on the genre and subgenre. However, when I test the backend on postman, it returns an empty array and I'm unsure if this has to do with my routes or the actual code that generates this list.
This is what my route looks like.
// get books based on the genre
router.get('/books/:genre', bookBuilder.get_some_books)
// get books based on multiple queries
router.get('/books/:genre&subgenre', bookBuilder.get_these_books)
This is the code that queries my MongoDB database
// getting book by genre & subgenre
exports.get_these_books = async function (req, res) {
let { genre, subgenre } = req.params;
try {
let books = await Book.find({"genre": genre, "subgenre": {$all: [subgenre]}});
if (books) {
res.json(books)
} else {
res.status(404).send({error: 'Not Found'});
}
} catch (err) {
res.status(500).send({error: err.message});
}
}
Getting a list of books by genre works just fine. But getting by genre AND subgenre is proving to be difficult.
EDIT:
The example document is
title:"Ghost Squad"
author: Array
genre:"MG"
subgenre: Array
0:"Ghost Story"
1:"Fantasy Fiction"
description:"Shortly before Halloween, Lucely and her best friend, Syd, cast a spel..."
As you can see, the subgenre is an array.

Sequelize returns wrong format from JSONB field

My "Item" model has a JSONB column named "formula".
I want to get it either as Object or JSON string. But what it returns is a string without quoted keys that can't be parsed as JSON.
My code:
async function itemsRead (where) {
const items = await models.item.findAll({
where
})
console.log(items)
return items
}
And what I see and get is:
[
item {
dataValues: {
id: 123,
formula: '{a:-0.81, x:5.12}',
}
},
.
.
.
]
My mistake was in insert (create) phase. I had to pass the original formula object (and not JSON stringified or other string forms) to create()
let formula = {a:-0.81, x:5.12}
models.item.create({id:123, formula})

Compare two fields in Waterline/Sails.js query

I want to compare two fields in my Waterline query in Sails.js application, e.g.: SELECT * FROM entity E WHERE E.current < E.max.
I've tried the following code, but it's expecting integer value to be passed to it instead of column name:
Entity.find({
where: {
current: {'<': 'max'}
}
});
So, how do I compare two columns?
I have ran some tests and at the same time read the Waterline documentation. There is no indication of anything that could possibly do comparison of two fields/columns via .find() or .where() methods. Reference: http://sailsjs.org/documentation/concepts/models-and-orm/query-language
Instead, I have used .query() method to compare two fields via SQL string such as :
Entity.query("SELECT * FROM `Entity` E WHERE E.current < E.max", function( err, res) {
if(err) {
//exception
} else {
console.log('response',res);
}
});
The other way would be to use one query to get the max before putting it in the criteria.
EntityOne.find({
sort: 'column DESC'
}).limit(1)
.exec(function(err,found){
var max = found[0]
EntityTwo.find({
where: {
current: {'<': found}
}
}).exec((err,found) {
// Do stuff here
});
});
The query method is ultimately going to be faster however

Update nested array object (put request)

I have an array inside a document of a collection called pown.
{
_id: 123..,
name: pupies,
pups:[ {name: pup1, location: somewhere}, {name: pup2, ...}]
}
Now a user using my rest-service sends the entire first entry as put request:
{name: pup1, location: inTown}
After that I want to update this element in my database.
Therefore I tried this:
var updatedPup = req.body;
var searchQuery = {
_id : 123...,
pups : { name : req.body.name }
}
var updateQuery = {
$set: {'pups': updatedPup }
}
db.pown.update(searchQuery, updateQuery, function(err, data){ ... }
Unfortunately it is not updating anythig.
Does anyone know how to update an entire array-element?
As Neil pointed, you need to be acquainted with the dot notation(used to select the fields) and the positional operator $ (used to select a particular element in an array i.e the element matched in the original search query). If you want to replace the whole element in the array
var updateQuery= {
"$set":{"pups.$": updatedPup}
}
If you only need to change the location,
var updateQuery= {
"$set":{"pups.$.location": updatedPup.location}
}
The problem here is that the selection in your query actually wants to update an embedded array element in your document. The first thing is that you want to use "dot notation" instead, and then you also want the positional $ modifier to select the correct element:
db.pown.update(
{ "pups.name": req.body.name },
{ "$set": { "pups.$.locatation": req.body.location }
)
That would be the nice way to do things. Mostly because you really only want to modify the "location" property of the sub-document. So that is how you express that.

Is there a way to query MongoDB Rest API with a list or array of IDs

I'm using a MEAN stack and with Mongoose. Is there a way to query MongoDB with multiple ids to only return those specific IDs in one query e.g. /api/products/5001,5002,5003
Is this possible or would I need to query each product individually or add an additional attribute to the products and query by that.
Update: To clarify as suggested below I've managed to get it partially working using {'_id': { $in: [5001,5002,5003]} however I'm having problems figuring out how to pass the list from the api url to the find function.
Using Express.js for router
router.get('/list/:ids', controller.showByIDs);
exports.showByIDs = function(req, res) {
Product.find({'_id': { $in: [req.params.ids]}}, function (err, product) {
if(err) { return handleError(res, err); }
if(!product) { return res.send(404); }
return res.json(product);
})
};
Then trying /api/products/list/5001 works however /api/products/list/5001,5002 doesn't. I'm not sure if it's a syntax problem in the url or my router code that needs to change or the controller.
You can use the $in operator to query for multiple values at once:
Products.find({_id: {$in: [5001, 5002, 5003]}}, function (err, products) { ... });
On the Express side, you need to use a format for the ids parameter that lets you split it into an array of id values, like you had in your first example:
/api/products/5001,5002,5003
Then in your route handler, you can call the split function on the req.params.ids string to turn it into an array of id values that you can use with $in:
exports.showByIDs = function(req, res) {
var ids = req.params.ids.split(',');
Product.find({'_id': { $in: ids}}, function (err, product) {
if(err) { return handleError(res, err); }
if(!product) { return res.send(404); }
return res.json(product);
})
};