How to update nested Objects - express

I want to use the $push method to push an object into a nested array. But i cant get it to work that you can dynamically get the right object inside of the array. Let me explain better by showing the code.
This is my Schema:
var StartedRaceSchema = new mongoose.Schema({
waypoints: {
type: Object,
name: String,
check_ins: {
type: Object,
user: {
type: Object,
ref: 'User'
}
}
}
});
When you check in on a waypoint, it has to be pushed in the correct waypoints nested Check_ins
This is the code for the update:
StartedRace.findByIdAndUpdate(req.params.id,
{ $push: { 'waypoints.1.check_ins': req.body.user } },
function (error) {
if (error) {
console.log(error)
res.send({
success: false,
error: error
})
} else {
res.send({
success: true
})
}
}
)
As you can see i can only get it to work with fields like:
'waypoints.1.check_ins'
That 1 needs to be dynamically because it gets send within the parameters.
But i can not get it to work dynamically, only hard coded.
Does anyone know how to do this?

Populate the collection with a list of check_ins enumerated by their ids.
waypoints.check_ins = {
...waypoints.check_ins,
[response.id]: response
}
You'd then have a list of check_ins that can referenced by their ids.

You could try this syntax instead of the dot notation:
let id = req.params.id;
StartedRace.findByIdAndUpdate(req.params.id,
{ $push: { waypoints: { id: { check_ins: req.body.user } } } }, { new : true } )
.exec()
.then(race => console.log(race))
.catch(err => err);
I used a Promise, but it's the same with a callback.

Related

Vue-apollo query doesn't render variables

In Nuxt.js, I'm trying to do a query like this with the nuxt apollo-module based in vue-apollo
apollo: {
magazines: {
query: gql`query($id: String!) {
magazines( where: { url_contains:$id })
{
url
title
thumbnail
}
}`,
prefetch: ({ route }) => ({ id: route.params.id }),
variables() {
return {
id: this.$route.params.id
}
}
}
The query is sent, but the variable $id is sent unrendered (in the petition, I can see query($id: String!)—instead of query('my-page-route': String!)— and where: { url_contains:$id } as it is—instead of where: { url_contains:'my-page-route' }
The query is surprisingly valid, as it responds with all the items in the db —so it doesn't apply the where: { url_contains:$id }
I have tried with query($id: String) but that doesn't change anything. Any hints about what could be going wrong?
Thanks in advance!

Vue Apollo: How can I query GraphQL using an object as Input argument?

I would like to create a checkout object via the GraphQL API provided by the Saleor eCommerce platform.
According to the gql playground there is a mutation to do so that takes a CheckoutCreateInput object as it's argument.
Here is an example mutation that works fine within the playground.
Here is the current code that I have tried (I am doing this within a vuex action)
export const actions = {
addToCart({ commit, dispatch }, cartItem) {
const currentCartItems = this.state.cartItems
// Check to see if we already have a checkout object
if (this.state.checkoutId !== '') {
// Create a new checkout ID
console.log('creating new checkout object')
try {
this.app.apolloProvider.defaultClient
.mutate({
mutation: CREATE_CART_MUTATION,
variables: {
checkoutInput: {
lines: { quantity: 10, variantId: 'UHJvZHVjdFZhcmlhbnQ6NQ==' },
email: 'test#test.com'
}
}
})
.then(({ data }) => {
console.log(data)
})
} catch (e) {
console.log(e)
}
} else {
console.log('checkout id already set')
}
// TODO: Check to see if the cart already contains the current Cart Item
commit('ADD_CART_ITEM', cartItem)
}
and here is the CREATE_CART_MUTATION:
import gql from 'graphql-tag'
export const CREATE_CART_MUTATION = gql`
mutation($checkoutInput: CheckoutCreateInput!) {
checkoutCreate(input: $checkoutInput) {
checkout {
id
created
lastChange
lines {
id
variant {
id
name
}
quantity
totalPrice {
gross {
localized
}
net {
localized
}
}
}
totalPrice {
gross {
localized
}
net {
localized
}
}
}
}
}
`
On the server this comes back with the following error:
graphql.error.base.GraphQLError: Variable "$checkoutInput" got invalid value {"email": "test#test.com", "lines": {"quantity": 10, "variantId": "UHJvZHVjdFZhcmlhbnQ6NQ=="}}.
In field "lines": In element #0: Expected "CheckoutLineInput", found not an object.
Looks like I was most of the way there, I was just passing a single lines object rather than an array of them. The correct code is as follows:
try {
this.app.apolloProvider.defaultClient
.mutate({
mutation: CREATE_CART_MUTATION,
variables: {
checkoutInput: {
lines: [
{ quantity: cartItem.quantity, variantId: cartItem.variantId }
],
email: 'test#test.com'
}
}
})
.then(({ data }) => {
console.log('mutation done!')
commit('SET_CHECKOUT_OBJECT', data.checkoutCreate.checkout)
})
} catch (e) {
console.log('error:')
console.log(e)
}

Sequelize model doesn't return in then block

I'm trying to return results back to my controller if sequelize properly updated a row. It works in the current code, but I can only return true whether is fails or works.
I have tried a few different way that I thought may work, but everything returns undefined in the controller unless I hard code "returns true"
Controller
const {promisify} = require('util');
const pageSection = promisify(db.pageSection);
exports.updateForm = async function (req, res) {
let result;
try {
result = await pageSection.updateSection(req);
} catch (err) {
console.log('** NOT GOOD **', err);
}
return res.send(result);
}
Model
pageSection.updateSection = function (req) {
var result;
pageSection.update ({
title: req.body.title,
description: req.body.description,
icon: req.body.icon
}, {
where: {
id: req.body.id
}
})
.then( updatedRow => {
return updatedRow; //Undefined in controller
sendResult( updatedRow ); //Still undefined
result = updatedRow; // Still undefined
})
.catch(err => {
console.log('Page Model Error: ', err);
})
function sendResult ( updatedRow ) {
if ( updatedRow ) { return true }
} //Returns undefined
return true; //Only thing that works
return result; //Undefined
}
(If you are using postgres)You need to add
returning: true,
plain: true
to your query right after the where clause, so that the updated rows of data are actually returned and setting plain:true ensures that what is returned are plain objects.
So now it would turn into:
pageSection.update ({
title: req.body.title,
description: req.body.description,
icon: req.body.icon
}, {
where: {
id: req.body.id
},
returning: true,
plain: true
})
the returned result is an array, so you'll need to access the second element of the returned array to get the updated rows.

adding a query to an axios get request

I am trying to restrict what gets returned by my axios get request.
I have a firebase backend and in my data i have a field called case_name, I have added a few records with the name Test and thought i could run the following in a get request to restrict my results to just those where case_name is equal to test, but it still returns all records
loadCase ({ commit, context }) {
return axios.get('http', {
params: {
case_name: 'Test'
}
})
.then(res => {
const convertcase = []
for (const key in res.data) {
convertcase.push({ ...res.data[key], id: key })
}
commit('listcase', convertcase)
})
.catch(e => context.error(e));
},
Can anyone tell me what im doing wrong please as cant find anything to help me at the moment
my returned object is
data: {…}
​​
"-LFXvk9yY5c-O8yIdf8k": Object { case_name: "Test", case_status: "live", case_summary: "This is some summary content", … }
​​
"-LFXwmv6eHqZs8jndNay": Object { case_name: "case 2", case_status: "live", case_summary: "dasdasdasdasd\nasd\ndasd\na\nsdasdasd", … }
​​
"-LFc2t9V7LVqnLAlIjoU": Object { case_name: "Test", case_status: "live", case_summary: "this is just another summary", … }
Thanks

How can I pass the value from my API to my head tittle with vue-head?

I am using vue-head in website because of I have to pass the name of the program to the html head, and the inf. it is coming from an API, so I make the request but every time I try to pass the name it send me error this the code:
export default {
data: () => ({
errors: [],
programs: [],
firstVideo: {},
vidProgram: {}
}),
},
created() {
//do something after creating vue instance
this.api = new ApiCanal({})
this.getProgram()
},
methods: {
getProgram() {
this.api.http.get(`videos/program/${this.programSlug}`)
.then(response => {
this.programs = response.data
this.firstVideo = response.data[0]
this.vidProgram = response.data[0]['program']
})
.catch(error => {
this.errors = error
});
}
},
head: {
//this is the inf. for the head
title: {
inner: this.programs.name,
separator: '-',
complement: this.programs.info
}
}
}
I will really appreciate if you can help me with this issue
If you want to use properties of your Vue object/component in the title there, you need to make it a function, as currently this refers to the object creating your Vue component (probably the global window object).
head: {
title: function() {
return {
inner: this.programs.name,
separator: '-',
complement: this.programs.info
};
}
}