Apollo GraphQl model attribute is not accessing object in ReactJs - reactjs

I am implementing category and subcategory display in ReactJs using Apollo GraphQl Query.
I tried to using same table as category with fields.
id,
category_name,
category_img,
category_parent_id ( id from same table),
category_status,
typeDefs and resolver are belows
Category.js
const typeDefs = gql`
extend type Query {
getSingleCategory(id: ID): allCategory
}
`;
type allCategory {
id: ID!
category_name: String
category_img: String
category_parent_id: Int
category_status: Status
}
const resolvers = {
Query: {
getSingleCategory: async (parent, args, context, info) => {
var data = await db.category.findOne({
where: {
id: args.id,
},
include: [
{
model: db.category,
as: "children",
attributes: [["category_name", "children_name"]],
nested: true,
required: false,
},
],
required: false,
});
return data;
},
},
},
Model in GraphQl
module.exports = function (sequelize, DataTypes) {
var category = sequelize.define(
"category",
{
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
category_name: {
type: DataTypes.STRING(256),
allowNull: false,
},
category_img: {
type: DataTypes.STRING(256),
allowNull: false,
},
category_parent_id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
references: {
// WorkingDays hasMany Users n:n
model: "category",
key: "children",
},
},
category_status: {
type: DataTypes.ENUM("Acitve", "Inactive"),
allowNull: false,
},
},
{
tableName: "category",
timestamps: false,
}
);
category.associate = function (models) {
models.category.belongsTo(models.category, {
onDelete: "CASCADE",
foreignKey: "category_parent_id",
as: "children",
targetKey: "id",
});
};
return category;
};
In ReactJs
category.ts
export const GET_CATEGORYBY_ID = gql`
query($catId: ID!) {
getSingleCategory(id: $catId) {
id
category_name
category_img
category_parent_id
category_status
}
}
`;
I am trying to accessing {data.getSingleCategory} , I got all parameters but not able to get children_name from same table as parent_name.
Anyone can tell me what is the issue I am not able to access that children_name as attribute from same table Or there any other way so that we can access category/subcategory from same table and display it to reactjs template.

Not defined [separately] in types, not used/defined [as 'children' property?] in parent type, not requested in query ... simply filtered out from response.

Related

Failed to save data into postgres database using sequelize.js, but system return column multiple times

While trying to save data into postgres database using sequelize BlogModel.create() system failed to save the data into table and server is returning columns createdat, updatedat, multiple times in console. ( please see below ). In the scheme I have added the column only once, can someone advise on this issue here ?
Executing (default): INSERT INTO "userBlogs" ("id","email","blogdetails","tags","createdat","updatedat","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING "id","email","blogdetails","tags","createdat","updatedat","createdAt","updatedAt";
//userBlogs.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const userBlogs = sequelize.define('userBlogs', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
email: {
type: DataTypes.STRING(255),
allowNull: false
},
blogdetails: {
type: DataTypes.TEXT,
allowNull: false
},
tags: {
type: DataTypes.STRING(255),
allowNull: false
},
createdat: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
},
updatedat: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
}, {
timestamps: true,
tableName: 'userBlogs'
});
return userBlogs;
};
//server.js
const usersBlogSchema = require('./modals/userBlogs');
const BlogModel = usersBlogSchema(sequelize, DataTypes);
app.post('/service/createblogs', async (req, res, next)=> {
try {
const userEmail = req.body.email;
const blogDetails = req.body.blogValue;
const tags = req.body.tagValue;
if (Object.keys(req.body).length === 0) {
res.status(403).json({ fail: "Invalid blog request or blog request is blank !" });
} else {
var requestData = {email:userEmail, blogdetails:blogDetails, tags:tags };
const createBlogRequest = await BlogModel.create(requestData);
res.status(200).json({ success: true });
}
} catch (e) {
console.log(e)
return next(e);
}
});
Returning createdAt and updatedAt multiple times because you have added columns (createdAt and updatedAt )and also timestamps:true ,
timestamps also adds these both columns
use either columns or timestamps
'use strict';
module.exports = (sequelize, DataTypes) => {
const userBlogs = sequelize.define('userBlogs', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
email: {
type: DataTypes.STRING(255),
allowNull: false
},
blogdetails: {
type: DataTypes.TEXT,
allowNull: false
},
tags: {
type: DataTypes.STRING(255),
allowNull: false
},
}, {
timestamps: true,
tableName: 'userBlogs'
});
return userBlogs;
};

Breaking down complex Prisma queries in Next.js app

I’ve got a Next.JS app. I want to render a todo feed on the homepage, but also the user page. I'm a bit stuck on how to break down my Prisma queries.
I fetch a big data object using getServerSideProps and pass this to the page component (and using react-query to hydrate and do re-fetching, but not relevant now)
- getRecentTodos (includes todos) for my homepage
- getUserDetailsByName (includes todos) for the user page
export type getRecentTodos = ReturnType<typeof getRecentTodos> extends Promise<
infer T
>
? T
: never
export const getRecentTodos = async (recentItemsAmount = 20) => {
return await prisma.todos.findMany({
where: { done: true },
select: {
id: true,
userId: true,
content: true,
done: true,
createdAt: true,
attachments: true,
todoReplies: {
select: {
id: true,
userId: true,
content: true,
todoReplyLikes: true,
todoId: true,
user: { select: { name: true, displayName: true, image: true } },
},
orderBy: { createdAt: 'asc' },
},
todoLikes: {
select: {
user: true,
},
},
user: {
select: {
name: true,
displayName: true,
image: true,
},
},
},
orderBy: { createdAt: 'desc' },
take: recentItemsAmount,
})
}
export const getUserDetailsByName = async (username: string) => {
return await prisma.user.findUnique({
where: {
name: username,
},
select: {
name: true,
displayName: true,
bio: true,
location: true,
twitter: true,
image: true,
createdAt: true,
todos: {
select: {
id: true,
content: true,
userId: true,
done: true,
updatedAt: true,
createdAt: true,
attachments: true,
user: true,
todoLikes: true,
todoReplies: {
take: 30,
orderBy: { createdAt: 'desc' },
select: {
id: true,
userId: true,
todoId: true,
createdAt: true,
content: true,
user: true,
},
},
},
take: 30,
orderBy: { createdAt: 'desc' },
},
projects: true,
},
})
}
Both queries return ‘todos,’ but they can return it in a slightly different way. The todo feed component expects certain properties to be available
- E.g. displayName on todoReplies
- But on getUserDetailsByName the displayName might not be part of the response or it’s nested one layer deeper or something
How to keep this from getting complex very fast?
You more or less want to select todos in your queries the same way (returning the same and omitting the same, apart of some things like order)
But manually keeping these things in sync over lot’s of queries qet’s complex quickly
Possible solutions?
Should I break the getServerSideProps into multiple fetches?
So instead of one ‘getUserDetailsByName’ which has todos as a relationfield included
fetch user details
fetch todos
This would mean I also have to write more react-query code for refetching etc… because you are dealing with multiple objects. But it does seperate concerns more.
Using Typescript to catch it in my codebase when a function tries to access a property which is not returned from that specific Prisma query? (I’m just now starting to see the possibilities of Typescript for stuff like this)
Should I just standardize the way the todos get created in a prisma query with a function and include that function inside of the Prisma queries? you can include like:
const todoSelect = {
id: true,
userId: true,
content: true,
{.......}
user: {
select: {
name: true,
displayName: true,
image: true,
},
},
}
export type getRecentTodos = ReturnType<typeof getRecentTodos> extends Promise<
infer T
>
? T
: never
export const getRecentTodos = async (recentItemsAmount = 20) => {
return await prisma.todos.findMany({
where: { done: true },
select: todoSelect,
orderBy: { createdAt: 'desc' },
take: recentItemsAmount,
})
}
const userSelect = {
name: true,
{......}
todos: {
select: todoSelect,
take: 30,
orderBy: { createdAt: 'desc' },
},
projects: true,
}
export const getUserDetailsByName = async (username: string) => {
return await prisma.user.findUnique({
where: {
name: username,
},
select: userSelect,
})
}

Sequelize unkown column in field list error

I have a MySql DB and using sequelize.
I have a recipe and ingredients tables.
I want to pass the ingredients as an array to the api.
So I researched and discovered I can use get/set to achieve this.
But I get an "Unknown coumn 'ingredients' in 'field list'".
This is my model. The line
console.info("getDataValue...", this);
never gets executed.
function model(sequelize) {
const attributes = {
recipeTitle: { type: DataTypes.STRING(255), allowNull: false },
category: { type: DataTypes.STRING(30), allowNull: false },
recipeSource: { type: DataTypes.STRING(100), allowNull: false },
recipeSourceData: { type: DataTypes.TEXT(), allowNull: true },
method: { type: DataTypes.TEXT(), allowNull: true },
comments: { type: DataTypes.TEXT(), allowNull: true },
prepTime: { type: DataTypes.STRING(10), allowNull: true },
cookTime: { type: DataTypes.STRING(10), allowNull: true },
rating: { type: DataTypes.FLOAT, allowNull: false },
owner_id: { type: DataTypes.INTEGER, allowNull: false },
ingredients: {
type: DataTypes.TEXT,
get() {
console.info("getDataValue...", this);
return JSON.parse(this.getDataValue("ingredients"));
},
set(val) {
if (!Array.isArray(val)) {
throw new Error("ingredients must to be an array");
}
this.setDataValue("ingredients", JSON.stringify(val));
},
},
};
This is my validate-request middle ware and it does have the ingredients
when i console.info("valreq...").
So it seems its the schema.validate that fails??
function validateRequest(req, next, schema) {
console.info("valreq...", req.body);
const options = {
abortEarly: false, // include all errors
allowUnknown: true, // ignore unknown props
stripUnknown: true, // remove unknown props
};
const { error, value } = schema.validate(req.body, options);
if (error) {
next(`Validation error: ${error.details.map((x) => x.message).join(", ")}`);
} else {
console.info("value...", value);
req.body = value;
next();
}
}

I am having difficulty accessing this nested array to carry out an update

SCHEMA
Below is my schema structure, kindly correct me if I am getting it wrong. I want to be able to update the ConnectState from false to true using an ObjectId
phones: {
type: String,
required: true,
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
// required: true,
},
Userpost: {
type: mongoose.Schema.Types.ObjectId,
ref: "userpost",
// required: true,
},
friendshipStatus: [
{
isFriend: {
FProfile: {
type: mongoose.Schema.Types.ObjectId,
ref: "profile",
},
ConnectStatus: {
type: Boolean,
default: false,
},
},
},
],
});
What I have tried
I want to update the Boolean value on ConnectStatus from false to true. I know I am getting the process wrong.
const result = await Profile.updateOne(
{ "friendshipStatus.isFriend.FProfile": uid },
{ $set: { "friendshipStatus.$.isFriend.ConnectStatus": true } },
{ arrayFilters: [{ "friendshipStatus.isFriend.FProfile": uid }] }
);
Try with:
const result = await Profile.update(
{ 'friendshipStatus.isFriend.FProfile': uid },
{ $set: { 'friendshipStatus.$.isFriend.ConnectStatus': true } },
);

Node Feathers Sequelize API invalid column name

I am setting up an API to a SQL Server 2008 database using Node, Feathers and Sequelize. I have successfully created the models and services using feathers-sequelize-auto, and most of the routes seem to be working. The app runs but with an error message:
Unhandled Rejection at: Promise {"_bitField":18087936,"_fulfillmentHandler0":{}}
I'm getting an error for one of the routes (/project) relating to one of its foreign keys. Postman output for /project is:
{
"name": "GeneralError",
"message": "Invalid column name 'OrganisationID'.",
"code": 500,
"className": "general-error",
"data": {},
"errors": {}
}
All works fine in the database itself, and I can run queries on the related tables with no issues.
Relevant parts of the Project.model.js:
Field definitions
LeadAgency: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: 'Organisation',
key: 'OrganisationID'
}
Relationships:
Project.associate = function(models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
Project.belongsTo(models.Team, { foreignKey: 'TeamID' });
Project.belongsTo(models.Subteam, { foreignKey: 'SubTeamID' });
Project.belongsTo(models.Staff, { foreignKey: 'StaffID' });
Project.belongsTo(models.Organisation, { foreignKey: 'OrganisationID' });
Project.belongsTo(models.Project, { foreignKey: 'ProjectID' });
};
And this is the Organisation.model.js code:
/* jshint indent: 2 */
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;
module.exports = function(app) {
const sequelizeClient = app.get('sequelizeClient');
const Organisation = sequelizeClient.define(
'Organisation',
{
OrganisationID: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
Name: {
type: DataTypes.STRING,
allowNull: false
},
Type: {
type: DataTypes.STRING,
allowNull: true
},
AddressID: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: 'Address',
key: 'AddressID'
}
}
},
{
tableName: 'Organisation',
timestamps: false
},
{
hooks: {
beforeCount(options) {
options.raw = true;
}
}
}
);
// eslint-disable-next-line no-unused-vars
Organisation.associate = function(models) {
// Define associations here
// See http://docs.sequelizejs.com/en/latest/docs/associations/
Organisation.belongsTo(models.Address, { foreignKey: 'AddressID' });
};
return Organisation;
};
Noob here so could be missing something obvious. Help appreciated!
I got this error due to incorrect mappings in model.associate. In your Project model you have defined Project as associate also. This can be the reason.

Resources