Closed mmmente closed 3 years ago
Hey @mmmente,
GraphQLStreamfield
should just work 🤔
did you decorate ButtonBlock
with register_streamfield_block
, or at least define graphql_fields
in it?
Would help to have the fullwe code here
Hey @zerolab,
thanks for getting back to me. Yes, I even can query the buttons
ListBlock
.
I reduced the code to relevant parts, as everything is exactly like here: https://github.com/GrappleGQL/wagtail-grapple/tree/master/example except the added mainbutton
blocks.py
@register_streamfield_block
class ButtonBlock(blocks.StructBlock):
button_text = blocks.CharBlock(required=True, max_length=50, label="Text")
button_link = blocks.CharBlock(required=True, max_length=255, label="Link")
graphql_fields = [GraphQLString(
"button_text"), GraphQLString("button_link")]
@register_streamfield_block
class TextAndButtonsBlock(blocks.StructBlock):
text = blocks.TextBlock()
buttons = blocks.ListBlock(ButtonBlock())
mainbutton = ButtonBlock()
graphql_fields = [
GraphQLString("text"),
GraphQLImage("image"),
GraphQLStreamfield("buttons"),
GraphQLStreamfield("mainbutton"),
]
Everything is migrated and data is entered.
Query:
{
page(id: 7) {
... on BlogPage {
body {
id
__typename
... on TextAndButtonsBlock {
rawValue
text
mainbutton {
rawValue
... on ButtonBlock {
buttonText
buttonLink
}
}
buttons {
__typename
... on ButtonBlock {
buttonText
buttonLink
}
}
}
... on CalloutBlock {
text
image {
url
}
}
}
}
}
}
Result form that Query:
{
"errors": [
{
"message": "'str' object has no attribute 'value'",
"locations": [
{
"line": 13,
"column": 15
}
],
"path": [
"page",
"body",
0,
"mainbutton",
0,
"rawValue"
]
},
{
"message": "'str' object has no attribute 'value'",
"locations": [
{
"line": 13,
"column": 15
}
],
"path": [
"page",
"body",
0,
"mainbutton",
1,
"rawValue"
]
}
],
"data": {
"page": {
"body": [
{
"id": "0e41a821-1c05-455b-b553-0a6a725078b9",
"__typename": "TextAndButtonsBlock",
"rawValue": "{'text': 'Am Ende kommt das!', 'buttons': [StructValue([('button_text', 'alles ansehen'), ('button_link', 'www.google.com')]), StructValue([('button_text', 'nichts ansehen'), ('button_link', 'www.google.com')])], 'mainbutton': StructValue([('button_text', 'HAUPTLINK'), ('button_link', 'www.facebook.de')])}",
"text": "Am Ende kommt das!",
"mainbutton": [
null,
null
],
"buttons": [
{
"__typename": "ButtonBlock",
"buttonText": "alles ansehen",
"buttonLink": "www.google.com"
},
{
"__typename": "ButtonBlock",
"buttonText": "nichts ansehen",
"buttonLink": "www.google.com"
}
]
}
]
}
}
}
I just realized, that when I only query the typenames of mainbutton
and buttons
, mainbutton
is reported as a StreamFieldBlock
, while buttons comes out as ButtonBlock
:
{
page(id: 7) {
... on BlogPage {
body {
__typename
... on TextAndButtonsBlock {
mainbutton {
__typename
}
buttons {
__typename
}
}
}
}
}
}
Result:
{
"data": {
"page": {
"body": [
{
"__typename": "TextAndButtonsBlock",
"mainbutton": [
{
"__typename": "StreamFieldBlock"
},
{
"__typename": "StreamFieldBlock"
}
],
"buttons": [
{
"__typename": "ButtonBlock"
},
{
"__typename": "ButtonBlock"
}
]
}
]
}
}
}
Hope this helps to get some more insight :)
To me,
mainbutton {
rawValue
}
... on ButtonBlock {
buttonText
buttonLink
}
}
should read
mainbutton {
... on ButtonBlock {
rawValue
buttonText
buttonLink
}
}
but it could be just an artifact of copy pasting different bits of code to make the example relevant to the issue. If that is the case, then we'll investigate closer
Hi @zerolab, you're right, it should read that and I edited the comment to be correct. It was just a mistake due to the copy pasting.
@mmmente thank you for this. It reminded of a similar issue I experienced this week on a project but did not get time to look into.
Submitted a PR #118 -- can you give it a go?
The tl;dr of it is that the nested StructBlock's field were defined as a list of fields which in turn would fail to resolve. Changed to allow settings is_list=False
(so you'd do GraphQLStreamfield("mainbutton", is_list=False)
and this now resolves correctly
Wow, that was fast, @zerolab
I gave it a go, with setting GraphQLStreamfield("mainbutton", is_list=False)
, no other changes.
Query:
{
page(id: 7) {
... on BlogPage {
body {
id
__typename
... on TextAndButtonsBlock {
rawValue
text
mainbutton {
rawValue
... on ButtonBlock {
buttonText
buttonLink
}
}
buttons {
__typename
... on ButtonBlock {
buttonText
buttonLink
}
}
}
}
}
}
}
Result:
{
"errors": [
{
"message": "'StreamValue' object has no attribute 'id'",
"locations": [
{
"line": 5,
"column": 9
}
],
"path": [
"page",
"body",
"id"
]
}
],
"data": {
"page": {
"body": {
"id": null,
"__typename": "StreamFieldBlock"
}
}
}
}
It seems to me that now the StreamField on the Model (body
) is not correctly resolving.
Sorry, I pushed a change that broke things. Undid it. Can you try again with the latest from that PR?
Thanks @zerolab ! This fixes the issue and so far I did not come across any new bugs.
This is now on master. Will look at making a new release in the next day or two
Hi! I really like how easy it is to use Grapple to get a GraphQL API up and running! I just came across this. When having a StructBlock within a StructBlock, I cannot query it and the endpoint returns the error
"'str' object has no attribute 'value'"
To test this, I copied the provided example/home/blocks.py and extend it with this use case:
mainbutton
is the new field, which uses the sameButtonBlock
asbuttons
. Thebuttons
work just as intended, however,mainbutton
does return the error:Am I using the wrong GraphQLType here or is this an actual bug?
Thanks!