I'm trying to create a type of this object
const obj = {
0: {
title: 'lorem',
description: 'ipsum',
},
1: {
title: 'dolor',
description: 'sit',
},
...
}
Copilot suggest me this but didn't work, it's very similar to what need to do
type Spec {
title: String
description: String
}
type Specs {
[key: number]: Spec
}
type Product {
specs: Specs
}
Related
I'm trying to configure my commitlint prompt to show a list for type selection.
This is my config file (commitlint.config.js):
module.exports = {
extends: ['#commitlint/config-conventional'],
prompt: {
questions: {
type: {
description: "My description:",
enum: {
feat: {
description: 'A new feature',
title: 'Features',
},
fix: {
description: 'A bug fix',
title: 'Bug Fixes',
},
}
}
}
}
};
but is not working:
prompt type question
Trying to pass nested variables to the GraphQL query but my server gets only top-level variables (shopId), everything else is null.
I tried:
#1
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice(
$shopId: String!
$address1: String
$zip: String
$city: String
$countryCode: String
) {
calculatePackagePrice(
where: {
shopId: $shopId
destination: {
address1: $address1
zip: $zip
city: $city
countryCode: $countryCode
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
)
And #2:
export function CALCULATE_PACKAGE_PRICE({ shopId, destination }) {
return gql`
query CalculatePackagePrice {
calculatePackagePrice(
where: {
shopId: "${shopId}"
destination: {
address1: "${destination.address1}"
zip: "${destination.zip}
city: "${destination.city}"
countryCode: "${destination.countryCode}"
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
}
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE({
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
})
)
It works just fine when I hardcoded variables content to the queries. What I'm doing wrong?
Here is a helpful snippet from graphql docs,
All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server.
You're correctly passing in the variables as strings, but then trying (perhaps successfully, but I've never seen the syntax before) to create the object in the gql template string. Instead, create an input type for destination and where.
input WhereInput {
shopId: String!
destination: DestinationInput!
}
input DestinationInput {
address1: String!
zip: String!
city: String!
countryCode: String!
}
then change the query on the client (and update the server definition),
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice($where: WhereInput!) {
calculatePackagePrice(where: $where) {
name
price
userErrors {
field
message
}
}
}
`
then pass the variables like,
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
where: {
shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
}
)
The server side of graphql is with nodejs and express. This is the schema for graphql. It has one query which accepts DateT object having from and to dates.
var schema = buildSchema(`
type Query {
courseWithDate(
timeFilter: DateT
): Course
},
type Course {
...
from: String
to: String
},
type DateT{
from : String
to : String
}
`);
and this is how I am getting courses
I am able to run the application with this url
localhost:4000/graphql
This is the query I am using
query courseWithDate($from: dateFrom, $to: dateTo) {
courseWithDate(timeFilter: {
from: "${dateFrom}"
to: "${dateTo}"
}) {
title
...
}
}
with these parameters
{
"from": "2019-10-10","to":"2019-10-10"
}
Exception message I get is related to the input type I am trying to pass.
{
"errors": [
{
"message": "The type of Query.courseWithDate(timeFilter:) must be Input Type but got: DateT.",
"locations": [
{
"line": 6,
"column": 25
}
]
}
]
}
I'm not sure, but probably this style looks more like best practice
type Course {
id: Int
title: String
author: String
from: String
to: String
description: String
topic: String
url: String
}
input DateInput {
dateFrom: String!
dateTo: String!
}
type Query {
courseWithDate(input: DateInput!, name: String!): Course
}
And Query on client side should be:
{
courseWithDate(input: {
dateFrom: "${dateFrom}"
dateTo: "${dateTo}"
}
name: "${name}")
{
id
name
}
}
I have a nested javascript class (see below) that is exposed through my GraphQL server. Can I write a GQL schema that exposes this complex structure as a single object? (aka flattened).
The Nested Object
interface Promotion {
id
type
data: PromotionType1 | PromotionType2
}
interface PromotionType1 {
a
b
}
interface PromotionType2 {
c
d
}
The desired GQL query to access the Object
I want to write a GQL schema so that I can query this object as follows:
promotion(id: "123") {
id
type
... on PromotionType1 {
a
b
}
... on PromotionType2 {
c
d
}
}
Is this possible with GQL?
You can use GraphQLUnitType and GraphQLInterfaceType to be able to make that GraphQL query to access the object, if you restructure your nested object. It seems you intended to use inheritance while designing promotion types and ended up having the subtypes as a field in parent type. Instead the structure should be like:
interface Promotion {
id
type
}
interface PromotionType1 extends Promotion {
a
b
}
interface PromotionType2 extends Promotion {
c
d
}
Promotion is the base type. We can have it as GraphQLInterfaceType:
const PromotionType = new GraphQLInterfaceType({
name: 'PromotionInterface',
fields: {
id: { type: GraphQLID },
type: { type: GraphQLString }
}
});
You need instances of PromotionType1 and PromotionType2. So, these can be GraphQLObjectType.
const PromotionType1 = new GraphQLObjectType({
name: 'PromotionType1',
interfaces: [ PromotionType ],
fields: {
id: { type: GraphQLID },
type: { type: GraphQLString },
a: { type: GraphQLString },
b: { type: GraphQLString },
},
isTypeOf: value => value instanceof PromotionType1
});
const PromotionType2 = new GraphQLObjectType({
name: 'PromotionType2',
interfaces: [ PromotionType ],
fields: {
id: { type: GraphQLID },
type: { type: GraphQLString },
c: { type: GraphQLString },
d: { type: GraphQLString },
},
isTypeOf: value => value instanceof PromotionType2
});
If your have JS class Promotion1 for GraphQL type PromotionType1 and Promotion2 for PromotionType2, the GraphQLObjectType for exposing promotion data will be like:
var Promotion = new GraphQLUnionType({
name: 'Promotion',
types: [ PromotionType1, PromotionType2 ],
resolveType(value) {
if (value instanceof Promotion1) {
return PromotionType1;
}
if (value instanceof Promotion2) {
return PromotionType2;
}
}
});
You can then query promotion data with:
promotion(id: "123") {
id,
type,
... on PromotionType1 {
a,
b,
}
... on PromotionType2 {
c,
d,
}
}
You can check out this example.
One possible solution is to flatten the object structure in your resolver. This would avoid the need to do anything complex in your GQL schema.
I have a mongoose schema like the one below:
import mongoose from 'mongoose'
const ProjectSchema = new mongoose.Schema({
name: {
type: String
},
owner: {
type: String
},
member: {
type: String
},
updatedDate: {
type: Date
},
description: {
type: String
},
folder: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Folder'
},
dataSources: [{
name: {
type: String
},
updatedDate: {
type: Date
},
}],
propjectHistory: [{
no: {
type: Number
},
member: { // is this reference or just a string?
type: String
},
action: {
type: String
},
updatedDate: {
type: Date
},
}]
})
const Project = mongoose.model('Project', ProjectSchema)
And I integrated with graphql using graffiti and graffiti-mongoose.
However, the Graphiql documentation shows that I only have the ones below:
addProject(input: addProjectInput!):
name: String
owner: String
member: String
updatedDate: Date
description: String
folder: ID
clientMutationId: String!
I could successfully add project with a mutation query only using those parameters, but it seems that I cannot even send mutation query with projectHistory and dataSource, which are embedded inside project schema.
However, I can access projectHistory and dataSource when I send find queries.
I can't find any documentation about the problem.
sample mutation query without nested ones works.
mutation {
addProject(input:{
clientMutationId: "1"
name: "testproject",
owner: "keonwoo",
member: "keonwoo",
updatedDate: "2015-07-24T13:23:15.580Z",
description: "this is test project",
folder: "56fb93403eab9e1c14358fb7"
}){
clientMutationId
changedProjectEdge{
node{
_id
name
updatedDate
}
}
}
}
the above mutation returns the following:
{
"data": {
"addProject": {
"clientMutationId": "1",
"changedProjectEdge": {
"node": {
"_id": "56fb93ab3eab9e1c14358fb8",
"name": "testproject",
"updatedDate": "2015-07-24T13:23:15.580Z"
}
}
}
}
}
I am not using client like relay.
the problem was with the graffiti-mongoose library.
Turns out that maintainers of graffiti-mongoose just added embedded object feature and I did not update.