Why mongoose ignores "commentId" property in document.comments array? - arrays

I have a some code:
const taskId: number = req.body.taskId;
const text: string = req.body.text;
const task = await db.tasks.findOneAndUpdate(
{ taskId },
{ $push: { comments: [{
commentId: await db.getId(`task.${taskId}.commentId`),
taskId,
// #ts-ignore
author: Number(req.session.userId),
text,
timestamp: Date.now()
}] } }
).catch(e => {
console.error(e);
return res.status(400).json({ errors: [{ msg: "UNKNOWN_ERROR" }] });
});
if (!task) return res.json({ errors: [{ location: "query", msg: "NOT_FOUND", param: "taskId" }] });
return res.json(task);
But I have out (I skipped other properties):
{
...,
comments: [{
"timestamp": 1595833609905,
"_id": "5f1e7d09c1e15d4c8e0b71fa",
"taskId": 2,
"author": 435214391,
"text": "haha test comment"
}]
}
In comment property "commentId" is undefined.. But if I use
console.log({
commentId: await db.getId(`task.${taskId}.commentId`),
taskId,
// #ts-ignore
author: Number(req.session.userId),
text,
timestamp: Date.now()
})
I see the "commentId" property. Why it not saves in database? (Mongoose)

Okey, this is win. Error has been found in imports:
import TaskResponseSchema from './TaskResponse';
import TaskCommentSchema from './TaskResponse';
But okey:
import TaskResponseSchema from './TaskResponse';
import TaskCommentSchema from './TaskComment';

Related

How to update the value in action creator - react

i am trying to update my response in the action creator.
Once then i receive response i am updating the time zone(as of now hardcoded)
Here the response
data = [
{
"created": {timestamp: "2018-05-12T16:55:32Z", Id: "234j", name: "jim"}
"id": "804690986026920900000061579629"
"lastUpdated": {timestamp: "2018-05-12T16:55:32Z", Id: "234j", name: "jim"}
"note": "standard 9"
},
{
"created": {timestamp: "2018-05-12T17:49:32Z", Id: "444a", name: "antony"}
"id": "804690986026920900000061579630"
"lastUpdated": {timestamp: "2020-05-12T16:49:32Z", Id: "444a", name: "antony"}
"note": "standard 9"
},
{
"created": {timestamp: "2018-05-12T17:55:12Z", Id: "123m", name: "mark"}
"id": "804690986026920900000061579631"
"lastUpdated": {timestamp: "2020-05-12T17:49:12Z", Id: "123m", name: "mark"}
"note": "standard 9"
}
];
action.js
then((results) => {
const hardcodedValue = "2020-05-22T04:49:44Z"
const getLocaltime = results.data.map((updatetime)=>{
return {...updatetime, lastUpdated.timestamp:hardcodedValue}
//getting error at lastUpdated.timestamp
})
results.data = getLocaltime;
dispatch({
type: "RECEIVED_DATA",
payload: updateId === '' ? {} : results,
})
Thats not a valid object:
{ ...updatetime, lastUpdated.timestamp:hardcodedValue }
Try fixing it to:
{ ...updatetime, lastUpdated: { ...updatetime.lastUpdated, timestamp: hardcodedValue } }
You could also do it like this:
updatetime.lastUpdated.timestamp = hardcodedValue;
return {...updatetime}
This would update the lastUpdated object and since you return a new outer object, the reference would change and you would not lose any data.
The easiest way, since its new data and the object reference can stay the same, you can just mutate it like this:
then((results) => {
const hardcodedValue = "2020-05-22T04:49:44Z";
results.data.forEach((row) => {
row.lastUpdated.timestamp = hardcodedValue;
});
dispatch({
type: "RECEIVED_DATA",
payload: localAccountId === '' ? {} : results,
})

methods.myFunction().call() throws Returned values aren't valid, did it run Out of Gas? Error

I am using "web3": "1.0.0-beta.26" and is getting the following error...
Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.
I have rerun truffle migrate --reset and used the address generated as the TODO_LIST_ADDRESS but I am still getting the error above
Anyone encountered this before and knows how to solve it? Thanks
App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
account: "test",
taskCount: 0
};
}
componentDidMount() {
this.loadBlockchainData();
}
loadBlockchainData = async () => {
const ethereum = window.ethereum;
ethereum.autoRefreshOnNetworkChange = false;
const web3 = window.web3;
const web3Instance = new Web3(ethereum);
const enabledWeb3 = await ethereum.enable();
const accounts = await web3Instance.eth.getAccounts();
const accountAddress = await accounts[0];
this.setState({ account: accountAddress });
const todoList = new web3Instance.eth.Contract(
TODO_LIST_ABI,
TODO_LIST_ADDRESS
);
console.log("todoList ", todoList);
//! ERROR
const taskCount = await todoList.methods.taskCount().call();
console.log("taskCount ", taskCount);
this.setState({ taskCount });
};
render() {
return (
<div className="container">
<h1>Hey World</h1>
<p>Your Account: {this.state.account}</p>
<p>Task Count: {this.state.taskCount}</p>
</div>
);
}
}
export default App;
config.js
export const TODO_LIST_ADDRESS = "0xb0D64f6C317448efa56A33678d718Fd715DAeddd";
export const TODO_LIST_ABI = [
{
inputs: [],
payable: false,
stateMutability: "nonpayable",
type: "constructor"
},
{
constant: true,
inputs: [],
name: "taskCount",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
internalType: "uint256",
name: "",
type: "uint256"
}
],
name: "tasks",
outputs: [
{
internalType: "uint256",
name: "id",
type: "uint256"
},
{
internalType: "string",
name: "content",
type: "string"
},
{
internalType: "bool",
name: "completed",
type: "bool"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
internalType: "string",
name: "_content",
type: "string"
}
],
name: "createTask",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];

Cannot log data from JSON-server API with GraphQL

I have built an API with JSON-server and I am trying to fetch the data from it using React-Apollo Client.
I'm trying to log the data from API on the console with Query tag, restructure and print the data variable using console.log().
I have no idea why the function is getting print via console.log().
I have the current setup:
JSON server is running on PORT 4000
Server is running on PORT 5000
Client is running on PORT 3000
I am already using CORS tool
Below is my component:
const BOOKS_QUERY = gql`
query BooksQuery {
books {
title
author
editionYear
}
}
`;
<Query query={BOOKS_QUERY}>
{({ loading, error, data }) => {
if (loading) return <h4>Loading...</h4>;
if (error) console.log(error);
console.log(data);
return <h1>test</h1>;
}}
</Query>
The content below is code for my schema:
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: { type: GraphQLInt },
title: { type: GraphQLString },
author: { type: GraphQLString },
editionYear: { type: GraphQLInt }
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
books: {
type: new GraphQLList(BookType),
resolve(parent, args) {
return axios.get('http://localhost:4000/books').then((res) => res.data);
}
},
book: {
type: BookType,
args: {
id: { type: GraphQLInt }
},
resolve(parent, args) {
return axios.get(`http://localhost:4000/books/${args.id}`).then((res) => res.data);
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
API:
{
"books": [
{
"id": "1",
"title": "Java How To Program",
"author": "Deitel & Deitel",
"editionYear": "2007"
},
{
"id": "2",
"title": "Patterns of Enterprise Application Architecture",
"author": "Martin Fowler",
"editionYear": "2002"
},
{
"id": "3",
"title": "Head First Design Patterns",
"author": "Elisabeth Freeman",
"editionYear": "2004"
},
{
"id": "4",
"title": "Internet & World Wide Web: How to Program",
"author": "Deitel & Deitel",
"editionYear": "2007"
}
]
}
I only expect the API data to be logged on console.
Later I will render that data on screen.

Mongoose Update array in a document does not work as expected

I'm scratching my head since a couple day on how to update the content of an array with Mongoose.
Here is my schema to begin with:
const playedGameSchema = new Schema ({
created: Date,
updated: Date,
game: {
type: Schema.Types.ObjectId,
ref: 'game'
},
creator: {
id: {
type: Schema.Types.ObjectId,
ref: 'user'
},
score: Number
},
partners: [{
id: {
type: Schema.Types.ObjectId,
ref: 'user'
},
score: Number
}]
});
module.exports = mongoose.model('PlayedGame', playedGameSchema);
Basically, what I want to achieve is to, at the same time:
- Update the creator.score (successful with dot notation).
- Update the score key for each partner (unsuccessful).
Here is the result of a document created:
{
"creator": {
"id": "5b8544fa11235d9f02a9b4f1",
"score": 0
},
"_id": "5bb6375f5f68cc5c52bc93ae",
"game": "5b45080bb1806be939bfde03",
"partners": [
{
"_id": "5bb637605f68cc5cafbc93b0",
"id": "5b85497111235d677ba9b4f2",
"score": 0
},
{
"_id": "5bb637605f68ccc70ebc93af",
"id": "5b85497111235d677ba9b4f2",
"score": 0
}
],
"created": "2018-10-04T15:53:03.386Z",
"updated": "2018-10-04T15:53:03.386Z",
"__v": 0
}
As I said, I was able to change the score of the score creator by passing something like { "creator.score": 500 } as a second parameter, then I switch to trying to update the array.
Here is my lambda function to update the score for each partner:
export const update: Handler = (event: APIGatewayEvent, context: Context, cb: Callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const body = JSON.parse(event.body);
let partnersScore: object = {};
if(body.update.partners) {
body.update.partners.forEach((score, index) => {
const key = `partners.${index}.$.score`;
partnersScore = Object.assign(partnersScore, { [key]: score});
console.log(partnersScore);
});
}
connectToDatabase().then(() => {
console.log('connected', partnersScore)
PlayedGame.findByIdAndUpdate(body.id, { $set: { partners: partnersScore } },{ new: true})
.then(game => cb(null, {
statusCode: 200,
headers: defaultResponseHeader,
body: JSON.stringify(game)
}))
.catch(err => {
cb(null, {
statusCode: err.statusCode || 500,
headers: { 'Content-Type': 'text/plain' },
body: err
})});
});
}
Which passes a nice { 'partners.0.$.score': 500, 'partners.1.$.score': 1000 } to the $set.
Unfortunately, the result to my request is a partners array that contains only one empty object.
{
"creator": {
"id": "5b8544fa11235d9f02a9b4f1",
"score": 0
},
"_id": "5bb6375f5f68cc5c52bc93ae",
"game": "5b45080bb1806be939bfde03",
"partners": [
{
"_id": "5bb63775f6d99b7b76443741"
}
],
"created": "2018-10-04T15:53:03.386Z",
"updated": "2018-10-04T15:53:03.386Z",
"__v": 0
}
Can anyone guide me into updating the creator score and all partners score at the same time?
My thoughs about findOneAndUpdate method on a model is that it's better because it doesn't require the data to be changed outside of the BDD, but wanting to update array keys and another key seems very difficult.
Instead, I relied on a set/save logic, like this:
PlayedGame.findById(body.id)
.then(game => {
game.set('creator.score', update.creatorScore);
update.partners.forEach((score, index) => game.set(`partners.${index}.score`, score));
game.save()
.then(result => {
cb(null, {
statusCode: 200,
headers: defaultResponseHeader,
body: JSON.stringify(result)
})
})
.catch(err => {
cb(null, {
statusCode: err.statusCode || 500,
headers: { 'Content-Type': 'text/plain' },
body: JSON.stringify({ 'Update failed: ': err })
})});
})

How to remove Object from array using mongoose

I'm trying to remove an object from an array in a document using mongoose.
The Schema is the following:
var diveSchema = new Schema({
//irrelevant fields
divers: [{
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
meetingLocation: { type: String, enum: ['carpool', 'onSite'], required: true },
dives: Number,
exercise: { type: Schema.Types.ObjectId, ref: 'Exercise' },
}]
});
a possible entry can be
{
//irrelevant fields
"divers": [
{
"_id": "012345678",
"user": "123456789",
"meetingLocation": "carpool",
"exercise": "34567890",
},
{
"_id": "012345679",
"user": "123456780",
"meetingLocation": "onSite",
"exercise": "34567890",
}
]
}
Say I want to remove the entry where user is 123456789 (note I do not know the _id at this point).
How do I do this correctly?
I tried the following:
var diveId = "myDiveId";
var userIdToRemove = "123456789"
Dive.findOne({ _id: diveId }).then(function(dive) {
dive.divers.pull({ user: userIdToRemove });
dive.save().then(function(dive) {
//do something smart
});
});
This yieled no change in the document.
I also tried
Dive.update({ _id: diveId }, { "$pull": { "divers": { "diver._id": new ObjectId(userIdToRemove) } } }, { safe: true }, function(err, obj) {
//do something smart
});
With this I got as result that the entire divers array was emptied for the given dive.
What about this?
Dive.update({ _id: diveId }, { "$pull": { "divers": { "user": userIdToRemove } }}, { safe: true, multi:true }, function(err, obj) {
//do something smart
});
I solve this problem using this code-
await Album.findOneAndUpdate(
{ _id: albumId },
{ $pull: { images: { _id: imageId } } },
{ safe: true, multi: false }
);
return res.status(200).json({ message: "Album Deleted Successfully" });
Try this
Dive.update({ _id: diveId },{"$pull": { "drivers": {"user": "123456789"}}})
Try this async code
var diveId = "myDiveId";
var userIdToRemove = "123456789"
const dive=await Dive.findOne({ _id: diveId })
await dive.divers.pull({ user: userIdToRemove });
await dive.save();
Use this with try/catch:
await Group.updateOne(
{ _id: groupId },
{ $pull: { members: {id: memberId }}}
);

Resources