why region_code not storing properly? - magento

I am using Magento GraphQL api in my project. To create a customer address I used createCustomerAddress mutation(createCustomerAddress).
Below is the mutation that I have called to create the customer address :
mutation createAddress {
createCustomerAddress(
input: {
firstname: "test"
lastname: "name"
company: "networld"
telephone: "1231231231"
street: ["test address line 1", "test address line 2"]
city: "Rajkot"
region: { region:"Gujarat", region_code: "GJ" }
postcode: "360001"
country_code: IN
}
) {
id
prefix
firstname
lastname
middlename
city
company
country_code
default_billing
default_shipping
postcode
region {
region
region_code
}
street
suffix
telephone
vat_id
}
}
This is working properly and returning me the result as below :
{
"data": {
"createCustomerAddress": {
"id": 44,
"prefix": null,
"firstname": "test",
"lastname": "name",
"middlename": null,
"city": "Rajkot",
"company": "networld",
"country_code": "IN",
"default_billing": false,
"default_shipping": false,
"postcode": "360001",
"region": {
"region": "Gujarat",
"region_code": "GJ"
},
"street": [
"test address line 1",
"test address line 2"
],
"suffix": null,
"telephone": "1231231231",
"vat_id": null
}
}
}
But, now when I query to get the customer address, it returning wrong region_code.
Here is the query I written to get the customer address :
query{
customer{
addresses{
id
firstname
lastname
street
city
region{
region
region_code
}
country_code
postcode
telephone
}
}
}
Result :
{
"data": {
"customer": {
"addresses": [
{
"id": 44,
"firstname": "test",
"lastname": "name",
"street": [
"test address line 1",
"test address line 2"
],
"city": "Rajkot",
"region": {
"region": "Gujarat",
"region_code": "Gujarat"
},
"country_code": "IN",
"postcode": "360001",
"telephone": "1231231231"
}
]
}
}
}
As you can see, region_code in this query result and region_code in mutation result was different. Query not returning region_code that generated from the mutation. Mutation generated region_code was GJ and query returned region_code was Gujarat.
Can anyone help me why this is happening ? How to solve it ?

I just stumbled upon this bug myself in Magento 2.3.4 and it looks like it's buggy with the region_code. There's a workaround for this, try to send the region_id instead of region_code, like this:
mutation {
createCustomerAddress(input: {
region: {
region: "VendeƩ"
region_id: 799
}
country_code: FR
street: ["123 Main Street"]
telephone: "7777777777"
postcode: "77777"
city: "Phoenix"
firstname: "Bob"
lastname: "Loblaw"
default_shipping: true
default_billing: false
}) {
id
region {
region
region_code
}
country_code
street
telephone
postcode
city
default_shipping
default_billing
}
}
After this, if you retrieve the region_code, it will show fine. It looks like it has problems identifying the region by the region_code.

Related

Graphql Validation

My graphql schema looks like this:
type Query {
}
type Mutation {
addEmployee(
employeePayload: EmployeeRequest!
): EmployeeResponse
}
type EmployeeResponse {
transactionId: String!
status: String!
message: String!
}
type EmploymentHistory {
historyId: Int
}
type Address {
title: String
firstLine: String!
secondLine: String!
line3: String
county: String
country: String
postcode: String
}
type Employee {
employeeId: Int!
nationalityStatus: String!
issuingOfficeName: String!
surname: String
forenames: String
dateOfBirth: String
townOfBirth: String
countryOfBirth: String
gender: String
address: Address
}
type Details {
employmentHistory: [EmploymentHistory!]
employee: Employee!
}
type Meta {
messageId: String
action: String
}
input EmployeeRequest {
details: Details
meta: Meta
}
I have a json data , which looks like this:
{
"query": "mutation addEmployee($employeePayload:EmployeeRequest!){addEmployee(employeePayload: $employeePayload) { status transactionId message} }",
"variables": {
"employeePayload": {
"meta": {
"messageId": "4fc8ec8f-67ad-46d2-9fab-1234567",
"action": "Create"
},
"details": {
"employee": {
"employeeId": 123,
"nationalityStatus": "GBR",
"issuingOfficeName": "London",
"surname": "MARRIED",
"forenames": "LEON",
"address": {
"title": "MR",
"firstLine": "20 Maze street",
"secondLine": "Darlington",
"line3": "Darlington",
"county": "UNITED KINGDOM",
"country": "UNITED KINGDOM",
"postcode": "DW1H 9EX"
},
"dateOfBirth": "1980-05-18",
"townOfBirth": "SOME PLACE",
"countryOfBirth": "UNITED KINGDOM",
"gender": "M"
},
"employmentHistory": [
{
"historyId": 123
},
{
"historyId": 456
}
]
}
}
}
}
My code to validate the json against the schema is this:
try {
String query = "mutation addEmployee($employeePayload:EmployeeRequest!)
{addEmployee(employeePayload: $employeePayload) { status
transactionId message}}";
document = parser.parseDocument(query);
} catch (ParseCancellationException e) {
log.error("There seems to be an issue parsing the document" + e.getMessage());
}
Validator validator = new Validator();
List<ValidationError> validationErrors = validator.validateDocument(schema, document);
return validationErrors.isEmpty();
The query is not the full payload (that needs to be validated). The above validation always pass. Is there a way I can find the validation constraints like not null or wrong data type?

ReferenceManyFields (One to Many Relationship)

I am working on a project where I have to create one to many relationships which will get all the list of records referenced by id in another table and I have to display all the selected data in the multi-select field (selectArrayInput). Please help me out in this, if you help with an example that would be great.
Thanks in advance.
Example:
district
id name
1 A
2 B
3 C
block
id district_id name
1 1 ABC
2 1 XYZ
3 2 DEF
I am using https://github.com/Steams/ra-data-hasura-graphql hasura-graphql dataprovider for my application.
You're likely looking for "nested object queries" (see: https://hasura.io/docs/1.0/graphql/manual/queries/nested-object-queries.html#nested-object-queries)
An example...
query MyQuery {
district(where: {id: {_eq: 1}}) {
id
name
blocks {
id
name
}
}
}
result:
{
"data": {
"district": [
{
"id": 1,
"name": "A",
"blocks": [
{
"id": 1,
"name": "ABC"
},
{
"id": 2,
"name": "XYZ"
}
]
}
]
}
}
Or...
query MyQuery2 {
block(where: {district: {name: {_eq: "A"}}}) {
id
name
district {
id
name
}
}
}
result:
{
"data": {
"block": [
{
"id": 1,
"name": "ABC",
"district": {
"id": 1,
"name": "A"
}
},
{
"id": 2,
"name": "XYZ",
"district": {
"id": 1,
"name": "A"
}
}
]
}
}
Setting up the tables this way...
blocks:
districts:
Aside: I recommend using plural table names as they are more standard, "districts" and "blocks"

Accessing json array in AWS AppSync

I am new to AWS AppSync and am trying to use an HTTP endpoint to fetch data from an external API. Here is an example of what that API returns.
{
"status": 1,
"size": 3,
"result": [
{
"number": "123",
"program": "program name",
"team_name": "team name",
"robot_name": "robot name",
"organisation": "team organization",
"city": "team city",
"region": "team state",
"country": "team country",
"grade": "team grade",
"is_registered": 0
},
{
"number": "456",
"program": "program name",
"team_name": "team name",
"robot_name": "robot name",
"organisation": "team organization",
"city": "team city",
"region": "team state",
"country": "team country",
"grade": "team grade",
"is_registered": 0
},
{
"number": "789",
"program": "program name",
"team_name": "team name",
"robot_name": "robot name",
"organisation": "team organization",
"city": "team city",
"region": "team state",
"country": "team country",
"grade": "team grade",
"is_registered": 0
}
]
}
Here is my GraphQL Schema
type Query {
getTeams(number: String!): Team
}
type Team {
number: String
program: String
teamName: String
robotName: String
organization: String
city: String
region: String
country: String
grade: String
isRegistered: Int
}
schema {
query: Query
}
Here is my request mapping template
{
"version": "2018-05-29",
"method": "GET",
"resourcePath": "/v1/get_teams",
"params":{
"query": {
"APIKEY": "API_KEY_GOES_HERE"
},
"headers": {
"Content-Type": "application/json"
}
}
}
And here is my response mapping template
#if($context.result.statusCode == 200)
## Success - decode the body and reconstruct the response with the schema in mind
#set($response = $util.parseJson($context.result.body))
#set($result = {
"number": $response.result[0].number,
"program": $response.result[0].program,
"teamName": $response.result[0].team_name,
"robotName": $response.result[0].robot_name,
"organization": $response.result[0].organisation,
"city": $response.result[0].city,
"region": $response.result[0].region,
"country": $response.result[0].country,
"grade": $response.result[0].grade,
"isRegistered": $response.result[0].is_registered
})
$util.toJson($result)
#else
## Error - send the proper error message
$utils.appendError($ctx.result.body, $ctx.result.statusCode)
#end
What I have currently worked but only returns one team. My question is how can I get the GraphQL query to return an array of teams by getting all of the items from the result array in the JSON file?
I'm not sure if I really understood what you are trying to achieve but here it goes:
If you want to return an array of teams instead of a single team, you have to modify your query in the schema as follow:
type Query {
getTeams: [Team]
}
Now on the response mapping you can map directly the response to your array:
#if($ctx.result.statusCode == 200)
## If response is 200, return the body.
$util.toJson($util.parseJson($ctx.result.body).result)
#else
## If response is not 200, append the response to error block.
$utils.appendError($ctx.result.body, "$ctx.result.statusCode")
#end
At this point I noticed that you renamed the fields in your schema so it does not match anymore; for example your json is returning team_name but your graphQL schema is expecting teamName.
What I would do is to modify the schema to match with the JSON as follow:
type Team {
number: String
program: String
team_name: String
robot_name: String
organisation: String
city: String
region: String
country: String
grade: String
is_registered: Int
}
And then use alias in the query to return the fields with the expected name, for example:
query{
getTeams{
number: number
teamName:team_name
robotName: robot_name
organization: organisation
}
}
That will produce the output that I think that you are expecting:
{
"data": {
"getTeams": [
{
"number": "123",
"teamName": "team name",
"robotName": "robot name",
"organization": "team organization"
},
....

Unable to do a mutation with a property of type "array of objects" in apollo

I'm new to all graphql world, so this might be a very easy question, sorry
I'm using graphql-compose-mongoose to generate my graphql schema, here's my mongoose schema:
const ComplainSchema = new Schema({
entityId: {type: String, required: true},
user: {type: UserInfoSchema, required: true},
title: String, // standard types
desc: String,
state: {required: true, type: String, enum: ["DRAFT", "MODERATION", "PUBLIC", "SOLVED"]},
attachments: [{
url: {type: String, required: true},
name: String,
mimeType: String,
attachmentId: Schema.Types.ObjectId
}],
createdAt: {type: Date, index: true},
updatedAt: {type: Date, index: true},
}, {timestamps: {}})
export default mongoose.model('Complaint', ComplainSchema)
If I attempt the following mutation in graphiql it works fine
mutation {
complaintUpdateById(record:{_id:"5bdd9350fe144227042e6a20", title:"ok", desc:"updated", attachments:[{name:"zied", url:"http://zied.com"}]}){
recordId,
record{
_id,
entityId,
user {
userId,
userName,
roleInShop
},
title,
desc,
createdAt,
updatedAt,
attachments{
name,
url
}
}
}
}
and returns this (in case there could be helpful to see the response)
{
"data": {
"complaintUpdateById": {
"recordId": "5bdd9350fe144227042e6a20",
"record": {
"_id": "5bdd9350fe144227042e6a20",
"entityId": "5bd9b1858788f51f44ab678a",
"user": {
"userId": "5bd9ac078788f51f44ab6785",
"userName": "Zied Hamdi",
"roleInShop": "ASA"
},
"title": "ok",
"desc": "updated",
"createdAt": "2018-11-03T12:23:44.565Z",
"updatedAt": "2018-11-05T09:02:51.494Z",
"attachments": [
{
"name": "zied",
"url": "http://zied.com"
}
]
}
}
}
}
Now if I try to pass the attachments to apollo, I don't know how to do that, I don't know which type to provide (Attachment is not the right type obvisouly):
const UPDATE_COMPLAINT = gql `mutation complaintUpdateById($_id:MongoID!, $title: String!, $desc: String!, $attachments: [Attachment]
)
{
complaintUpdateById(record:{_id:$_id, title:$title, desc:$desc, attachments:$attachments}){
recordId,
record{
_id,
entityId,
user {
userId,
userName,
roleInShop
},
title,
desc,
createdAt,
updatedAt
}
}
}`
So searching for the right type, I did a introspection of my object, the issue is that I get the type of attachment as null for this query:
{
__type(name: "Complaint") {
kind
name
fields {
name
description
type {
name
}
}
}
}
this is the response:
{
"data": {
"__type": {
"kind": "OBJECT",
"name": "Complaint",
"fields": [
{
"name": "entityId",
"description": null,
"type": {
"name": "String"
}
},
{
"name": "user",
"description": null,
"type": {
"name": "ComplaintUser"
}
},
{
"name": "title",
"description": null,
"type": {
"name": "String"
}
},
{
"name": "desc",
"description": null,
"type": {
"name": "String"
}
},
{
"name": "state",
"description": null,
"type": {
"name": "EnumComplaintState"
}
},
{
"name": "attachments",
"description": null,
"type": {
"name": null
}
},
{
"name": "createdAt",
"description": null,
"type": {
"name": "Date"
}
},
{
"name": "updatedAt",
"description": null,
"type": {
"name": "Date"
}
},
{
"name": "_id",
"description": null,
"type": {
"name": null
}
}
]
}
}
}
googling didn't help since I don't know how is this operation called, I don't think it's a nested mutation from what I found...
Ok fixed,
I did these steps:
I first introspected the type of attachment in a regular query using the __typename keyword: as follows
mutation {
complaintUpdateById(record:{_id:"5bdd9350fe144227042e6a20", title:"ok", desc:"updated", attachments:[{name:"zied", url:"http://zied.com"}]}){
recordId,
record{
_id,
entityId,
user {
userId,
userName,
roleInShop
},
title,
desc,
createdAt,
updatedAt,
attachments{
__typename,
name,
url
}
}
}
}
it showed up a type named ComplaintAttachments
when replacing the Attachment type with this new value, ComplaintAttachments, an error occured and that error message helped me out:
Variable "$attachments" of type "[ComplaintAttachments]" used in
position expecting type "[ComplaintComplaintAttachmentsInput]"
so the array is of type ComplaintComplaintAttachmentsInput, I still don't know how to introspect it directly, but I'm already happy with the result :)

hasManyThrough is returning only one result instead of all

The platform has a many to many relationship, where the table assigned_users holds all Users assigned to CalendarEvents.
I need to fetch, through CalendarEvents, the assigned users as an object, showing each user's information. So, I want to access the User through AssignedUsers, because I wanna fetch all the users related to that event.
public function assignedUsers()
{
return $this->hasManyThrough(Users::class, AssignedUsers::class, 'user_id', 'id');
}
It works, but it shows only the first user in the table. I want to show all of them. Currently there are 3.
"assigned_users": [
{ id: 1, ... }
]
If I do the following:
public function assignedUsers()
{
return $this->belongsToMany(Users::class, "assigned_users", "event_id", "event_id");
}
It will fetch 3 results, but all the information will be from the same user. It will repeat the same user 3 times. Changing both the event_id to user_id and id, and id and user_id will have the same result.
"assigned_users": [
{ id: 1, ... },
{ id: 1, ... },
{ id: 1, ... },
...
]
What I am trying to accomplish is the following result:
{
"status": "200",
"success": true,
"data": [
{
"event_id": 1,
"event_key": "EB1M7OGJRPW0",
"calendar_id": 4,
"start_at": "2018-01-01 00:00:00",
"end_at": "2018-01-31 00:00:00",
"location": "123 Lorem, Ipsum",
"event_name": "Event #1",
"description": "Lorem ipsum dolor sit amet",
"added_at": "2018-02-07 09:07:31",
"created_by": {
"id": 4,
"name": "Foo Bar",
"email": "foobar92#gmail.com",
"first_name": "Foo",
"last_name": "Bar",
"status": "active",
"is_activated": 0,
"created_at": "2018-02-07 09:06:49",
"updated_at": "2018-02-07 09:06:49"
},
"assigned_users": [
{
"id": 1,
...
},
{
"id": 2,
...
},
{
"id": 3,
...
},
...
]
}
]
}
This is not the case of hasManyThrough relationship. Here assigned_users is a pivot table so you just need a belongsToMany relationship defined
public function assignedUsers()
{
return $this->belongsToMany(Users::class, 'assigned_users', 'event_id', 'user_id');
}
and for this to work, you may have to change the calendar_events table's primary key to id (instead of event_id)

Resources