Why mongo crop an array before save? - ajax

I try to save the object to a collection of mongoDb.
The object contents array of objects (name 'Children'). If the Children array length more than 20, mongo returns me empty Children array (it contents only one object with mongo's _id property).
How can I determine where is the error?
var object = {
"BrowseNodeId": "2619526011",
"Name": "Appliances",
"IsCategoryRoot": "1",
"Children": [{
"BrowseNodeId": "3737671",
"Name": "Air Conditioners"
},
// Here 30 objects {}
],
"Ancestors": {
"BrowseNodeId": "2619525011",
"Name": "Appliances"
},
};
I use $.ajax to make a post query:
$.ajax({
url: 'http://localhost:8005/api/category',
data: object,
method: 'POST',
dataType: 'application/json'
}).done((res) => {
console.log(res);
// => returns object with Children.length == 1
})
But If I use the Postman to make a post query - object comes to me with Children array length as I expect == 20.
Mongoose schema:
mongoose.model('category', new mongoose.Schema(
{
BrowseNodeId: Number,
Name: String,
Children: [{
BrowseNodeId: Number,
Name: String,
}],
Ancestors: {
BrowseNodeId: Number,
Name: String,
},
level: Number,
}
))
The implementation of http://localhost:8005/api/category:
var koa = require('koa');
var router = require('koa-router')();
var koaRestMongoose = require('koa-rest-mongoose');
var cors = require('koa-cors');
var mongoUrl = '127.0.0.1:27017/dbname';
var mongoose = require('mongoose');
mongoose.connect(mongoUrl);
var model = {
category: mongoose.model('category', new mongoose.Schema(
{
BrowseNodeId: Number,
Name: String,
Children: [{
BrowseNodeId: Number,
Name: String,
}],
Ancestors: {
BrowseNodeId: Number,
Name: String,
},
level: Number,
}
)),
item: mongoose.model('item', new mongoose.Schema(
{
BrowseNodeId: Number,
Name: String,
}
)),
}
var app = koa();
app.use(cors());
koaRestMongoose(app, router, model.category, '/api');
koaRestMongoose(app, router, model.item, '/api');
app.use(router.routes());
app.listen(8005);
I assume it may be schema issue
UPD
When I use ajax request body is:
Cat: { Name: 'Test',
'Children[0][BrowseNodeId]': '11',
'Children[1][BrowseNodeId]': '11' }
With the Postman request is:
Children: [ { BrowseNodeId: '11' }, { BrowseNodeId: '11' } ] }

Related

Mongoose refPath one path multi model populate

Used refPath here documentation: https://mongoosejs.com/docs/populate.html#dynamic-ref
const match = { $or: [{ build: variable }, { country: variable }], isDeleted: undefined };
const populate = [
{ path: `reviewer`, model: 'Build', select: { _id: 1, username: 1, } },
{ path: `reviewer`, model: 'Country', select: { _id: 1, username: 1 } },
];
const buildPopulate = await this.reviewsModel.find(match).select(select).populate(populate[0]).lean().exec();
const countryPopulate = await this.reviewsModel.find(match).select(select).populate(populate[1]).lean().exec();
return { buildPopulate, countryPopulate };
When i was try to populate with just one query i cant get populate[0] already get reviewer null.
I have find this solution but i think is not healthy solution. Anyone have idea ??

#ibm-cloud/cloudant: includeDocs: true, still not able to get the entire details of the documents

service.postAllDocs({
db: 'orders',
includeDocs: true,
limit: 10
}).then(response => { console.log(response.result)});
result only returns:
id, key and value(only contains rev)
To fetch the first 10 docs from the database, including the doc bodies, this code works:
const { CloudantV1 } = require('#ibm-cloud/cloudant')
const client = CloudantV1.newInstance()
const DBNAME = 'orders'
const main = async function () {
const response = await client.postAllDocs({ db: DBNAME, includeDocs: true, limit: 10 })
console.log(response.result.rows)
}
main()
This produces the following output:
[
{
id: '1',
key: '1',
value: { rev: '1-0fdc08a2625917344e37eb91661a5568' },
doc: {
_id: '1',
_rev: '1-0fdc08a2625917344e37eb91661a5568',
fruit: 'banana'
}
},
{
id: '2',
key: '2',
value: { rev: '1-8c4d4385540143ea87f8663193105425' },
doc: {
_id: '2',
_rev: '1-8c4d4385540143ea87f8663193105425',
fruit: 'apple'
}
}
]
The document body is under the doc attribute in each object.

How to implement interface using GraphQL and node

I want to achieve the fields of one object type within another object type
Here is my schema file.
const Films = new GraphQLInterfaceType({
name: 'films',
fields: () => ({
id:{
type: GraphQLID
},
name: {
type: GraphQLString,
},
})
})
const MovieStream = new GraphQLObjectType({
name: 'MovieStream',
interfaces: () => [Films],
fields: () => ({
id: {
type: GraphQLID,
},
movie_id: {
type: GraphQLString,
},
})
})
Here I am trying to use the interface. But It shows error:
{
"errors": [
{
"message": "Query root type must be Object type, it cannot be { __validationErrors: undefined, __allowedLegacyNames: [], _queryType: undefined, _mutationType: undefined, _subscriptionType: undefined, _directives: [#include, #skip, #deprecated], astNode: undefined, extensionASTNodes: undefined, _typeMap: { __Schema: __Schema, __Type: __Type, __TypeKind: __TypeKind, String: String, Boolean: Boolean, __Field: __Field, __InputValue: __InputValue, __EnumValue: __EnumValue, __Directive: __Directive, __DirectiveLocation: __DirectiveLocation, films: films, ID: ID, Date: Date, JSON: JSON, MovieStream: MovieStream }, _possibleTypeMap: {}, _implementations: { films: [] } }."
},
{
"message": "Expected GraphQL named type but got: { __validationErrors: undefined, __allowedLegacyNames: [], _queryType: undefined, _mutationType: undefined, _subscriptionType: undefined, _directives: [#include, #skip, #deprecated], astNode: undefined, extensionASTNodes: undefined, _typeMap: { __Schema: __Schema, __Type: __Type, __TypeKind: __TypeKind, String: String, Boolean: Boolean, __Field: __Field, __InputValue: __InputValue, __EnumValue: __EnumValue, __Directive: __Directive, __DirectiveLocation: __DirectiveLocation, films: films, ID: ID, Date: Date, JSON: JSON, MovieStream: MovieStream }, _possibleTypeMap: {}, _implementations: { films: [] } }."
}
]
}
Here is Query type:
const QueryRoot = new GraphQLObjectType({
name: 'Query',
fields: () => ({
getContentList:{
type: new GraphQLList(contentCategory),
args: {
id: {
type: GraphQLInt
},
permalink: {
type: GraphQLString
},
language: {
type: GraphQLString
},
content_types_id: {
type: GraphQLString
},
oauth_token:{
type: GraphQLString
}
},
resolve: (parent, args, context, resolveInfo) => {
var category_flag = 0;
var menuItemInfo = '';
user_id = args.user_id ? args.user_id : 0;
// console.log("context"+context['oauth_token']);
return AuthDb.models.oauth_registration.findAll({attributes: ['oauth_token', 'studio_id'],where:{
// oauth_token:context['oauth_token'],
$or: [
{
oauth_token:
{
$eq: context['oauth_token']
}
},
{
oauth_token:
{
$eq: args.oauth_token
}
},
]
},limit:1}).then(oauth_registration => {
var oauthRegistration = oauth_registration[0]
// for(var i = 0;i<=oauth_registration.ength;i++){
if(oauth_registration && oauthRegistration && oauthRegistration.oauth_token == context['oauth_token'] || oauthRegistration.oauth_token == args.oauth_token){
studio_id = oauthRegistration.studio_id;
return joinMonster.default(resolveInfo,{}, sql => {
return contentCategoryDb.query(sql).then(function(result) {
return result[0];
});
} ,{dialect: 'mysql'});
}else{
throw new Error('Invalid OAuth Token');
}
})
},
where: (filmTable, args, context) => {
return getLanguage_id(args.language).then(language_id=>{
return ` ${filmTable}.permalink = "${args.permalink}" and ${filmTable}.studio_id = "${studio_id}" and (${filmTable}.language_id = "${language_id}" OR ${filmTable}.parent_id = 0 AND ${filmTable}.id NOT IN (SELECT ${filmTable}.parent_id FROM content_category WHERE ${filmTable}.permalink = "${args.permalink}" and ${filmTable}.language_id = "${language_id}" and ${filmTable}.studio_id = "${studio_id}"))`
})
},
}
})
})
module.exports = new GraphQLSchema({
query: QueryRoot
})
Please help me out. have i done something wrong in the use of interface?
I have found the answer through this post
Is it possible to fetch data from multiple tables using GraphQLList
Anyone please tell me the exact way to use the interface in my code.
Although the error you have printed does not really relate to interfaces implementations, in order for you to use interfaces, you have to implement the methods/types the interface references. So in your situation your object MovieStream is missing the type name that you refer in the object Films.
Your code should look something like:
const Films = new GraphQLInterfaceType({
name: 'films',
fields: () => ({
id:{
type: GraphQLID
},
name: {
type: GraphQLString,
},
})
})
const MovieStream = new GraphQLObjectType({
name: 'MovieStream',
interfaces: () => [Films],
fields: () => ({
id: {
type: GraphQLID,
},
name: {
type: GraphQLString // You're missing this!
},
movie_id: {
type: GraphQLString,
},
})
})
Now back to the error you have printed "message": "Query root type must be Object type, it cannot be...
This seems to be related to your QueryRoot object, it seems that GraphQLSchema is not recognizing the root object. If this issue is still there once you fix the interface, have a look at this answer here

Graphql multiple arguments in field

I'm using GraphQL.
I'm able to pass one argument in a field. But I would like to know how to pass multiple arguments to a field.
This is my code:
GraphlQL Object type: Price availability
const priceAvailability = new GraphQLObjectType({
name: "priceAvailability",
description: "Check price and availability of article",
fields: () => ({
articleID: {
type: GraphQLString
},
priceType:{
type:GraphQLString
},
stockAvailability: {
type: StockAvailabilityType,
resolve(parentValue, args) {
// stuff to get the price and availability
return (data = getStockAvailability.getStockAvailability(
parentValue.isbn, parentValue.omgeving
));
}
}
})
});
The root query
const RootQuery = new GraphQLObjectType({
name: "RootQuery",
fields: () => ({
price: {
type: new GraphQLList(priceAvailability),
args: [{
articleID: {
type: new GraphQLList(GraphQLString),
description:
'List with articles. Example: ["artid1","artid2"]'
},
priceType: {
type: new GraphQLList(GraphQLString) ,
description:
'PriceType. Example: "SalePrice","CurrentPrice"'
}]
},
resolve: function(_, { articleID , priceType}) {
var data = [];
// code to return data here
return data;
}
}
})
});
Schema
module.exports = new GraphQLSchema({
query: RootQuery
});
This is the query I use in GraphiQL to test:
{
query: price(articleID:"ART03903", priceType:"SalePrice" ){
stockAvailability {
QuantityAvailable24hrs
QuantityAvailable48hrs
}
}
}
I can get the articleID via parentValue.articleID, but I have issues with getting parentValue.priceType.
Also GraphiQL tells me that priceType does not exists:
Unknown argument “priceType”. On field “price” of type “RootQuery”
args for a field takes an object instead of an array. Try:
args: {
articleID: {
type: new GraphQLList(GraphQLString),
description: 'List with articles. Example: ["artid1","artid2"]'
},
priceType: {
type: new GraphQLList(GraphQLString) ,
description: 'PriceType. Example: "SalePrice","CurrentPrice"'
},
}

how to set many-to-many relation in graphql mutation?

I may be missing something, but can not find any information on Apollo docs about the way to set a many-to-many relation when creating a new entry.
When the relation is one-to-many it is as simple as setting the ID of the one-side of the relationship in the many-side object.
But let's pretend I am working with Books and Authors, how would I write a graphql query that creates a Book for one (or many?) Authors?
This should probably happen at the API layer on the GraphQL server (i.e. schema). For many-to-many relationships, you should have a "join" type to denote the BookAuthor many-to-many relationship, and then add an entry to that join type.
Essentially then you'll have a type called Book, another called Author, and finally one more called BookAuthor. And you can add a few mutations to be able to manage that relationship. Perhaps...
addToBookAuthorConnection
updateBookAuthorConnection
removeFromBookAuthorConnection
This is a conventional setup using a Relay-spec compliant API. You can read more about how to structure your API for many-to-many relationships here.
Then, you only need to call the addToBookAuthorConnection mutation from Apollo instead to be able to add to that many-to-many connection on your frontend.
Hope this helps!
If u r using apollo graph server with one to many relations then connectors.js, resolvers.js and schema.js files as given formats
schema.js
const typeDefinitions = `
type Author {
authorId: Int
firstName: String
lastName: String
posts: [Post]
}
type Post {
postId: Int
title: String
text: String
views: Int
author: Author
}
input postInput{
title: String
text: String
views: Int
}
type Query {
author(firstName: String, lastName: String): [Author]
posts(postId: Int, title: String, text: String, views: Int): [Post]
}
type Mutation {
createAuthor(firstName: String, lastName: String, posts:[postInput]): Author
updateAuthor(authorId: Int, firstName: String, lastName: String, posts:[postInput]): String
}
schema {
query: Query
mutation:Mutation
}
`;
export default [typeDefinitions];
resolvers.js
import { Author } from './connectors';
import { Post } from './connectors';
const resolvers = {
Query: {
author(_, args) {
return Author.findAll({ where: args });
},
posts(_, args) {
return Post.findAll({ where: args });
}
},
Mutation: {
createAuthor(_, args) {
console.log(args)
return Author.create(args, {
include: [{
model: Post,
}]
});
},
updateAuthor(_, args) {
var updateProfile = { title: "name here" };
console.log(args.authorId)
var filter = {
where: {
authorId: args.authorId
},
include: [
{ model: Post }
]
};
Author.findOne(filter).then(function (product) {
Author.update(args, { where: { authorId: args.authorId } }).then(function (result) {
product.posts[0].updateAttributes(args.posts[0]).then(function (result) {
//return result;
})
});
})
return "updated";
},
},
Author: {
posts(author) {
return author.getPosts();
},
},
Post: {
author(post) {
return post.getAuthor();
},
},
};
export default resolvers;
connectors.js
import rp from 'request-promise';
var Sequelize = require('sequelize');
var db = new Sequelize('test', 'postgres', 'postgres', {
host: '192.168.1.168',
dialect: 'postgres',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
const AuthorModel = db.define('author', {
authorId: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, field: "author_id" },
firstName: { type: Sequelize.STRING, field: "first_name" },
lastName: { type: Sequelize.STRING, field: "last_name" },
},{
freezeTableName: false,
timestamps: false,
underscored: false,
tableName: "author"
});
const PostModel = db.define('post', {
postId: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, field: "post_id" },
text: { type: Sequelize.STRING },
title: { type: Sequelize.STRING },
views: { type: Sequelize.INTEGER },
},{
freezeTableName: false,
timestamps: false,
underscored: false,
tableName: "post"
});
AuthorModel.hasMany(PostModel, {
foreignKey: 'author_id'
});
PostModel.belongsTo(AuthorModel, {
foreignKey: 'author_id'
});
const Author = db.models.author;
const Post = db.models.post;
export { Author, Post };

Resources