I'm using kendo ui data grid with a firebase (rest json response). The structure can contain multiple objects. However, these objects are not in a standard array format. See my json file below:
{
"users": {
"contactdetails": {
"email": "johnlittle#email.com"
},
"firstname": "John",
"id": 1,
"surname": "Little"
}
}
I am able to read firstname and surname onto the grids column but cannot get to the email object.
This is my schema definition:
schema: {
model: {
fields: {
id: {type: "number"},
firstname: {type: "string"},
surname: {type: "string"},
email: {type: "string"}
}
}
}
As far I know, u can not specify nested object to schema model definition. One way is you can use column template for email column.
columns: [
{ field: "firstname", title: "FirstName" },
{ field: "surname", title: "Surename" },
{ title: "Email", template: "#= data.contactdetails.email #" },
],
Related
I tried to make schema to validate json such this:
{
"integration": { "module": [ "m" ] },
"tile": {
"title": "TTT",
"text": "ttt",
"icon": "./resources/main-icon.png",
"tags": [ "bbb", "vvvv"],
"orderNumber": 20
},
"steps": {
"order": [
"1",
"2",
"3"
],
"data": {
"1": {
"title": "tt1",
"description": "",
"screens": { "default": "true" }
},
"2": {
"title": "tt2",
"description": "",
"screens": { "default": "true" }
},
"3": {
"title": "tt3",
"description": "",
"screens": { "default": "true" }
}
}
}
};
Schema:
Joi.object({
integration: Joi.object({
module: Joi.array().items(Joi.string().valid('m').required())
}).required(),
tile: Joi.object({
title: Joi.string().required(),
text: Joi.string().required(),
icon: Joi.string().required(),
tags: Joi.array().items(Joi.string()).required(),
orderNumber: Joi.number().integer().min(1).max(255).required()
}).required(),
steps: Joi.object({
order: Joi.array().items(Joi.string()).required(),
data: Joi.object().keys({
title: Joi.string().required(),
description: Joi.string().required(),
screens: Joi.object({
default: Joi.string().valid('true', 'false').required()
}).required()
}).unknown(),
}).required()
});
But it generate error:
Validation Error: "steps.data.title" is required. "steps.data.description" is required. "steps.data.screens" is required
Please help. How can I make this schema?
Your data key is an object with keys 1, 2, and 3, each one is also an object with keys title, description, and screens.
But in your validation, your data key is an object with keys title, description, and screens, which is not correct.
You should change your steps.data validation to this:
data: Joi.object().pattern(
Joi.string().valid("1", "2", "3"),
Joi.object().keys({
title: Joi.string().required(),
description: Joi.string().required().allow(''),
screens: Joi.object({ default: Joi.string().valid('true', 'false').required() }),
})).unknown(),
}).required()
I used Joi.object().pattern to avoid duplicating the code since your object value is the same for each key.
I also changed your data.description, since you were not allowing empty strings, I just added .allow('').
I am trying to create two GraphQL types, Item and Listing, which contain instances of each other as fields. In GraphQL type language they would be:
type Item {
id: ID!
name: String!
...
listings: [Listing]!
}
type Listing {
id: ID!
price: Int!
...
item: Item!
}
(... represents irrelevant omitted fields)
I've seen other projects do this so I know it's possible, but I'm having difficulty doing this with github.com/graphql-go/graphql. From what I've learned online the way to do this using Go would be:
var ItemType graphql.Type = graphql.NewObject(
graphql.ObjectConfig {
Name: "Item",
Fields: graphql.Fields {
"id": &graphql.Field {
Type: graphql.ID,
},
"name": &graphql.Field {
Type: graphql.String,
},
...
"listings": &graphql.Field {
Type: graphql.NewList(ListingType),
},
},
},
)
var ListingType graphql.Type = graphql.NewObject(
graphql.ObjectConfig {
Name: "Listing",
Fields: graphql.Fields {
"id": &graphql.Field {
Type: graphql.ID,
},
"price": &graphql.Field {
Type: graphql.Int,
},
...
"item": &graphql.Field {
Type: ItemType,
},
},
},
)
but this results in an initialization loop:
./test.go:9:5: initialization loop:
/home/william/Desktop/test.go:9:5: ItemType refers to
/home/william/Desktop/test.go:26:5: ListingType refers to
/home/william/Desktop/test.go:9:5: ItemType
I understand that this happens because the compiler needs to know the size of ItemType in order to determine the size of ListingType in order to determine the size of ItemType (and on and on...) but I'm not sure how to get around it.
The recommended way of handling this is using AddFieldConfig:
houseType := &graphql.Object{...}
residentType := &graphql.Object{...}
houseType.AddFieldConfig("residents", &graphql.Field{Type: graphql.NewList(residentType)})
residentType.AddFieldConfig("houses", &graphql.Field{Type: graphql.NewList(houseType)})
I'm using AWS appsync along with DynamoDB for my project, and I have the following schema:
type List {
id: String!
title: String!
items: [String!]! ## it's of String Set (SS) type on DynamoDB
}
type Item {
id: String!
name: String!
}
I want to get a specific list along with their items. the ids of these items are in the List object. e.g
e.g:
List
{
id: "list0001",
title: "My First list",
items: ["item_001", "item_002"]
}
Item
{
id: "item_001",
name: "Item 001"
}
I want to have the following result when querying list0001
{
id: "list0001",
title: "My First list",
items: [
{
id: "item_001",
name: "Item 001"
},
{
id: "item_002",
name: "Item 002"
}
]
}
I know that I can have the list id on Item type and then I use that id to fetch the items but I want to have it as described above by getting the items from the set of the string in List type. I want to know whether it's feasible. if so, what are the mapping templates for both queries.
N.B: I'm using serverless for my project with serverless-appsync-plugin plugin.
You could set this up with two tables, ListTable and ItemTable.
The ListTable would store the information about lists. An example entry would look like:
{
"id": "list_0000",
"title": "List0"
}
The ItemTable would be used to to relate Items to the List that they belong to. An example entry would look like:
{
"id": "item_0001",
"name": "item1",
"listId": "list_0000"
}
You would need to modify your schema as follows:
type List {
id: String!
title: String!
items: [Item!]! ## A List of Items
}
type Item {
id: String!
name: String!
}
type Query {
getList(listId: ID!): List
}
This setup would request setting up 2 resolvers, 1 on getList and 1 on the field items of the type List.
Your request mapping template for getList would look like:
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.args.listId),
}
}
The response mapping template would be:
$util.toJson($ctx.result)
Your request mapping template for items of the type List would look like:
{
"version" : "2018-05-29",
"operation" : "Query",
"query" : {
"expression": "listId = :listId",
"expressionValues" : {
":listId" : { "S": "$ctx.source.id" }
}
}
}
The response mapping template would be:
$util.toJson($ctx.result.items)
Running the query:
query {
getList(listId: "list_0000") {
id
title
items {
id
name
}
}
}
Would have a result like:
{
"data": {
"getList": {
"id": "list_0000",
"title": "List0",
"items": [
{
"id": "item_0001",
"name": "item1"
}
]
}
}
}
I'm using the Go implemenatation of GraphQL.
How would you configure a mutation so that it can receive arguments with more than 1 level?
For exemple, here is the list of arguments I would like to pass to a mutation CreateUser:
mutation createUser($user: CreateUser!) {
createUser(input: $user)
}
{
"user": {
"name": {
"first": "John",
"last": "Doe"
},
"email": "john#doe.com"
}
}
(Notice that I dont want to use firstname and lastname but a name object instead)
And this is my (unsuccessful) attempt so far:
var CreateUserInput = graphql.FieldConfigArgument{
"input": &graphql.ArgumentConfig{
Description: "Input for creating a new user",
Type: graphql.NewNonNull(graphql.NewInputObject(graphql.InputObjectConfig{
Name: "CreateUser",
Fields: graphql.InputObjectConfigFieldMap{
"name": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.NewInputObject(graphql.InputObjectConfig{
Fields: graphql.InputObjectConfigFieldMap{
"first": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
"last": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
})),
},
"email": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
})),
},
}
Apparently the subfields first and last are not recognized as this is what I get when I run this mutation:
{
"data": null,
"errors": [
{
"message": "Variable \"$user\" got invalid value {\"email\":\"john#doe.com\",\"name\":{\"first\":\"john\",\"last\":\"doe\"}}.\nIn field \"name\": In field \"first\": Unknown field.\nIn field \"name\": In field \"last\": Unknown field.",
"locations": [
{
"line": 1,
"column": 21
}
]
}
]
}
Is this even possible?
EDIT: See comments in the accepted answer for the solution.
This are my first ever lines of Go but I will try to convey what I think the problem is.
First lets talk about the structure you want to be going for. I will use SDL here:
type Mutation {
createUser(user: CreateUser!): Boolean! # Maybe return user type here?
}
input CreateUser {
name: CreateUserName!
email: String!
}
input CreateUserName {
first: String!
last: String!
}
Okay now that we know that we need two input types lets get started!
var CreateUserName = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "CreateUserName",
Fields: graphql.InputObjectConfigFieldMap{
"first": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
"last": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
})
var CreateUser = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "CreateUser",
Fields: graphql.InputObjectConfigFieldMap{
"name": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(CreateUserName),
},
"email": &graphql.InputObjectFieldConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
})
Now all that should be left is adding the mutation field to your mutation object type.
http://jsfiddle.net/N8Svz/5/
I'm sure I must be doing something kind of dumb; this seems like a textbook usage of HeirarchicalDataSource as far as I can tell.
var domtree = [{
"id": "linear1",
"element-class": "LinearLayout",
"children": [{
"id": "static1",
"element-class": "Static"
}, {
"id": "static2",
"element-class": "Static",
"children": [{
"id": "static3",
"element-class": "Static"
}]
}, {
"id": "4",
"element-class": "Error"
}]
}];
var inline = new kendo.data.HierarchicalDataSource({
data: domtree,
schema: {
model: {
id: "id",
children: "children"
}
}
});
$("#navtree").kendoTreeView({
dataSource: inline,
dataTextField: "id"
});
A big thank you to anyone who can point out what I'm doing wrong!
I just change the field children to items.
here's a jsfiddle: http://jsfiddle.net/nn007/N8Svz/6/
If you add the schema property like this it may work. You are telling the hierarchical datasource what the key for children is. Something like this:
schema: { model: { children: "children" } }