DynamoDB: ValidationException: The provided key element does not match the schema - javascript

I'm getting the error ValidationException: The provided key element does not match the schema trying to find the field username in my database, when querying the id manually I get a response but with the username I get the error.
const readKey = async (table, queryData, column) => {
const params = {
TableName: table,
Key: {},
}
// { TableName: 'users', Key: { username: 'Maarten' } }
params.Key[column] = queryData
return await new Promise((res, rej) => {
dynamodb.get(params, (err, data) => {
if (err) {
rej(err)
console.log(err)
}
console.log(data)
res(data)
})
})
}
The response:
message: 'The provided key element does not match the schema',
code: 'ValidationException',
time: 2019-11-24T23:50:37.472Z,
requestId: 'RHQF02LFVE7V3NNSGDBF8JR97RVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 14.742327788838905
when I change the params to this:
const params = {
TableName: table,
Key: {
id: '22601770-37ea-47ce-9814-bd979ca4c841',
},
}
I get the response:
{
Item: {
id: '22601770-37ea-47ce-9814-bd979ca4c841',
password: '$2b$10$f/gXRrSCCALPRedCIxOwVuhzi2EX07DeEDVF4h10UuUN.DgYY2Hnq',
username: 'Maarten'
}
}
What am I doing wrong?

Related

Graphql resolveType union: throwing must resolve to an object type at runtime

I'm querying a union type in graphql, data comes from MongoDB database, driver: Mercurius, with Fastify framework. I'm trying to implement a search, by fetching data from 2 different database, for example one fetching products the other blog post, so I'm using union to list them both, but the error seems to be persistent.
Below is my schema
interface Details {
_id: String!
}
type Temp {
min: String
max: String
mean: String!
}
type Surface implements Details {
orderFromSun: Int!
name: String!
hasRings: Boolean!
_id: String!
surfaceTemperatureC: Temp!
}
type MainAtmos implements Details {
orderFromSun: Int!
name: String!
hasRings: Boolean!
_id: String!
mainAtmosphere: [String]
}
type User implements Details {
_id: String!
username: String!
active: Boolean!
email: String!
accounts: [String]
}
union SearchResult = Surface | User
type Query {
add(x: Int, y: Int): Int
planets: [MainAtmos]
single_planet(id: String!): Surface
search(text: String!): [SearchResult!]
searchUsers(text:String!): [User]
}
and here's my resolver:
const resolvers = {
Query: {
add: async (_, { x, y }) => x + y,
planets: async (_, args, context, info) => {
const result = await db.find().toArray();
return result
},
single_planet: async (_, args, context, info) => {
const result = await db.findOne({ _id: ObjectId(args.id) })
return result
},
search: async (_, { text }, context, info) => {
const result = await db.aggregate([{
'$search': {
'index': 'default',
'text': {
'query': text,
'path': {
'wildcard': '*'
}
}
}
}]).toArray();
const response = await usersDB.aggregate([{
'$search': {
'index': 'customers',
'text': {
'query': text,
'path': {
'wildcard': '*'
}
}
}
}]).toArray();
// return result
const finalResponse = [...result, ...response];
return finalResponse
},
searchUsers: async (_, { text }, context, info) => {
const response = await usersDB.aggregate([{
'$search': {
'index': 'customers',
'text': {
'query': text,
'path': {
'wildcard': '*'
}
}
}
}]).toArray();
return response
}
},
SearchResult: {
__resolveType: (parameter, context, info) => {
// return username ? 'User' : 'Surface'
if (parameter.hasRings) {
return 'Surface';
}
if (parameter.username) {
return 'User';
}
return null;
}
},
}
and the error message
"Abstract type \"SearchResult\" must resolve to an Object type at runtime for field \"Query.search\". Either the \"SearchResult\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."
Is there anything I might have done wrong? Here's my query:
query SearchResult {
search(text: "Elizabeth Ray ch4") {
__typename
... on Surface {
name
hasRings
}
... on User {
email
accounts
}
}
}
SearchResult: {
//-- __resolveType
resolveType: (parameter, context, info) => {
// return username ? 'User' : 'Surface'
if (parameter.hasRings) {
return 'Surface';
}
if (parameter.username) {
return 'User';
}
return null;
}
},
Change __resolveType to resolveType.

How can I find a Post of a User?

Hello I want to find posts which user has made ..
I do my request with JWT Token:
###
http://localhost:8080/forum/getByOwnerID
Authorization: Bearer {{token}}
This is my create function :
exports.create = async (req, res) => {
const { forumName, forumDescription } = req.body;
const token = req.token;
const forumExist = await Forum.findOne({ forumName: req.body.forumName });
if(forumExist){
res.status(400).send("Forum Exists already.");
}
try{
const owner = await User.findOne({userID:token._id});
if (!forumName || !forumDescription) {
res.status(400);
throw new Error("Please Fill all the feilds");
return;
}
else {
const newForum = new Forum({ forumName, forumDescription,user: owner.userID });
newForum.user = owner;
const createdNote = await newForum.save();
res.status(201).json(createdNote);
}
}catch(err){
res.status(400).send(err);
}
};
This is my function where I want to get the Posts which the user has made :
exports.getByToken = async (req, res, next) => {
const forum = await Forum.findById( {user: req.token._id} );
if (forum) {
res.json(forum);
} else {
res.status(404).json({ message: "Forum not found" });
}
res.json(forum);
}
And this is model which I have for Post:
const forumSchema = ({
forumName: {
type: String,
required: true,
},
forumDescription: {
type: String,
required: true,
},
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
published_on: {
type: String,
default: moment().format("LLL")
},
});
Everytime I do a request it has this error :
UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "{ user: 'admin' }" (type Object) at path "_id" for model "Forum"
my generate Token :
const generateToken = (_id, userID) => {
console.log('Signing token for ID ', _id,userID);
console.log('Secret key is ', process.env.JWT_KEY);
const token = jwt.sign({ _id,userID}, process.env.JWT_KEY, {
expiresIn: "30d",
});
console.log('Signed token: ', token);
return token;
};
As you are using findById, you should only send the id as argument function.
If you want to search with filter query, use find method

error: MongoError: Performing an update on the path '_id' would modify the immutable field '_id'

I tried using const course ={....} instead of const course = new course({...}) and also removing the _id from it, but to no avail. I tried taking hints by using logger but that too didnt depict my issue.
course.js
router.put(
"/:id",
(req, res, next) => {
const course = new Course({
_id: req.body.id,
coursename: req.body.coursename,
duration: req.body.duration,
strength: req.body.strength
});
logger.trace('Details: ', course);
logger.trace(req.body);
Course.updateOne({ _id: req.params.id }, course).then(result => {
logger.trace('Result: ', result);
if (result.nModified > 0) {
res.status(200).json({ message: "Update successful!" });
}
else {
res.status(401).json({ message: "Access Denied!" });
}
})
.catch(err => {
console.log('error: ', err);
});
}
);
Here's the updatePosts() function of course.service.ts file that I use for linking with backend for course
updatePosts(id: string, coursename: string, duration: string, strength: number) {
let CData: courseData | FormData;
CData = new FormData();
CData.append("id", id);
CData.append("coursename", coursename);
CData.append("duration", duration);
CData.append("strength", strength.toString());
this.http
.put("http://localhost:3300/api/admin/courses/" + id, CData)
.subscribe(response => {
const updatedCourses = [...this.courses];
const oldPostIndex = updatedCourses.findIndex(p => p.id === id);
const post: courseData = {
id: id,
coursename: coursename,
duration: duration,
strength: strength
};
updatedCourses[oldPostIndex] = post;
this.courses = updatedCourses;
this.coursesUpdated.next([...this.courses]);
// this.router.navigate(["/"]);
});
}

Sequelize update information

I've been struggling with this issue for a day now and can't seem to figure out a way to resolve it. This is the code I'm running
Client side:
const nameInput = document.querySelector("#nameInput");
const urlInput = document.querySelector("#urlInput");
const rowAlert = document.querySelector(".alertAppend");
const divAlert = document.createElement("div");
const nameUpdate = async (e) => {
e.preventDefault();
fetch("/auth/updateName", {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
},
body: JSON.stringify({
name: nameInput,
url: urlInput,
})
})
.then(function (data) {
console.log('Request success: ', data);
})
.catch(function (error) {
console.log('Request failure: ', error);
});
};
submitName.addEventListener("click", nameUpdate);
API:
router.get("/updateName", auth, async (req, res) =>{
try {
const { name, url } = req.body;
const ime = name;
const uid = req.session.passport.user;
db.User.find({ where: { id: uid } })
.on('success', function (user) {
if (user) {
user.update({
name: ime,
webhook: url
})
.success(function () {})
}
})
res.json({ message: url});
} catch (err) {
if (err) res.status(500).json({ message: "Internal Error"})
}
});
For some reason it just runs the select query and never proceeds to update the user.
Chrome console output
Debug console output
Sequelize model in case it helps:
module.exports = function (sequelize, DataTypes) {
var User = sequelize.define("User", {
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
password: {
type: DataTypes.STRING,
allowNull: false
},
name: {
type: DataTypes.STRING
}
})
return User;
}
The issue was in the API, it's supposed to be router.post
router.post("/updateName", auth, async (req, res) =>{
const { ime, url } = req.body;
const uid = req.session.passport.user;
console.log(ime);
db.User.findOne({where: {id: uid}})
.then(record => {
let values = {
name: ime,
webhook: url
}
record.update(values).then( updatedRecord => {
console.log(`updated record ${JSON.stringify(updatedRecord,null,2)}`)
res.status(200).json({ message: "success"});
})
}
})
.catch((error) => {
// do seomthing with the error
throw new Error(error)
})
});
You can try the following code
await db.User.update({
name: ime,
webhook: url
}, { where: { id: uid } });
When defining your model I don't see the webhook field

Search for particular results with a certain string in GraphQL

I want to search with my query getFoodType to return results based on whether the foodType of particular restaurant/takeaway is a "Chicken","Pizza" etc
Like this foodType: "Chicken"
I've tried using arguments and mongoDB filters (it's a MongoDB server) but no luck.
Schema
const EaterySchema = new Schema({
name: {
type: String,
required: true
},
address: {
type: String,
required: true
},
foodType: {
type: String,
required: true
}
});
My Schema Types
type Eatery {
id: String!
name: String!
address: String!
foodType: String!
}
type Query {
eatery(id: String!): Eatery
eateries: [Eatery]
getFoodType(foodType: String): [Eatery]
}
My Resolver
getFoodType: () => {
return new Promise((resolve, reject) => {
Eatery.find({})
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res);
});
});
},
Current Query in Apollo Playground
{
getFoodType (foodType: "Chicken") {
id
name
address
foodType
}
}
I essentially want to return all the results with "Chicken" as a the foodType. Something like foodType: "Chicken".
First, you need to get the value of the foodType to be queried in Resolver
const resolvers = {
Query: {
getFoodType: (_, args) => {
const { foodType } = args
...
},
},
}
Then use foodType when querying
Eatery.find({ foodType })
Finally need to return the result
new Promise((resolve, reject) => {
return Eatery.find({ foodType })
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res)
})
})
Complete example
const resolvers = {
Query: {
getFoodType: (_, args) => {
const { foodType } = args
return new Promise((resolve, reject) => {
return Eatery.find({ foodType })
.populate()
.exec((err, res) => {
err ? reject(err) : resolve(res)
})
})
},
},
}
Use the async/await
const resolvers = {
Query: {
getFoodType: async (_, { foodType }) => {
try {
const eaterys = await Eatery.find({ foodType }).populate()
return eaterys
} catch (e) {
// Handling errors
}
},
},
}

Categories

Resources