View more context

 

unclecheese

'Hero' => $this->manager->getType(StaticSchema::inst()->typeName(File::class))

👍 (1)
Anthony van Beek

hahaha, now got this

  1. "errors": [
  2. {
  3. "message": "Type 'SilverStripe_Assets_File' is not a registered GraphQL type",
Anthony van Beek

but under scaffolding types I have:

  1. SilverStripe\Assets\File:
  2. fieldsExcept: [Content]
  3. fields: [File]
Anthony van Beek

In my Course class I define Hero as

  1. private static $has_one = array(
  2. 'Hero' => Image::class,
  3. );
Anthony van Beek

I changed it to 'Hero' => $this->manager->getType(StaticSchema::inst()->typeName(DBFile::class)),

Anthony van Beek

now I get

  1. [Emergency] Uncaught Error: Cannot use object of type GraphQL\Type\Definition\ObjectType as array
  2. POST /graphql/
  3. Line 172 in /vagrant/vendor/silverstripe/graphql/src/TypeCreator.php
  4.  
  5. Source
  6. 163 * or resolveField().
  7. 164 *
  8. 165 * @param string $name Name of the field
  9. 166 * @param array $field Field array specification
  10. 167 * @return callable|null The callback, or null if there is no field resolver
  11. 168 */
  12. 169 protected function getFieldResolver($name, $field)
  13. 170 {
  14. 171 // Preconfigured method
  15. 172 if (isset($field['resolve'])) {
  16. 173 return $field['resolve'];
  17. 174 }
  18. 175 $candidateMethods = [
  19. 176 'resolve'.ucfirst($name).'Field',
  20. 177 'resolveField',
  21. 178 ];
Anthony van Beek

Ok so I got 'Hero' => ['type' => $this->manager->getType(StaticSchema::inst()->typeName(DBFile::class))],

Anthony van Beek

back to this error

  1. [Notice] Undefined index: type
  2. POST /graphql/
  3. Line 142 in /vagrant/vendor/webonyx/graphql-php/src/Type/Definition/FieldDefinition.php
  4.  
  5. Source
  6. 133 }
  7. 134
  8. 135 /**
  9. 136 * FieldDefinition constructor.
  10. 137 * @param array $config
  11. 138 */
  12. 139 protected function __construct(array $config)
  13. 140 {
  14. 141 $this->name = $config['name'];
  15. 142 $this->type = $config['type'];
  16. 143 $this->resolveFn = isset($config['resolve']) ? $config['resolve'] : null;
  17. 144 $this->mapFn = isset($config['map']) ? $config['map'] : null;
  18. 145 $this->args = isset($config['args']) ? FieldArgument::createMap($config['args']) : [];
  19. 146
  20. 147 $this->description = isset($config['description']) ? $config['description'] : null;
  21. 148 $this->deprecationReason = isset($config['deprecationReason']) ? $config['deprecationReason'] : null;
Anthony van Beek

So I assume I need to to add DBFile into my types

Anthony van Beek

Did that now I got:

  1. [Emergency] Uncaught InvalidArgumentException: "SilverStripe\Assets\Storage\DBFile" is not a DataObject subclass
  2. GET /dev/graphiql?flush=1&flushtoken=d846b537df35fd67c13ff607cc88473a
  3. Line 77 in /vagrant/vendor/silverstripe/graphql/src/Scaffolding/Traits/DataObjectTypeTrait.php
  4.  
  5. Source
  6. 68 if (!$class) {
  7. 69 throw new InvalidArgumentException("Missing class provided");
  8. 70 }
  9. 71
  10. 72 if (!class_exists($class)) {
  11. 73 throw new InvalidArgumentException("Non-existent classname \"{$class}\"");
  12. 74 }
  13. 75
  14. 76 if (!is_subclass_of($class, DataObject::class)) {
  15. 77 throw new InvalidArgumentException("\"{$class}\" is not a DataObject subclass");
  16. 78 }
  17. 79
  18. 80 $this->dataObjectClass = $class;
  19. 81 return $this;
  20. 82 }
  21. 83 }
unclecheese

It should be added in SchemaScaffolder::registerFixedTypes, no?

unclecheese

huh.. can you debug why SchemaScaffolder isn't adding it in registerFixedTypes?

Anthony van Beek

should I add SchemaScaffolder::registerFixedTypes somewhere?

unclecheese

no, it should be called in SchemaScaffolder::addToManager.. can you debug that?

Anthony van Beek

I’ve added

  1. public function addToManager(Manager $manager)
  2. {
  3. dump('running manager');
  4. dump($manager);
unclecheese

just for fun, try wrapping the return statement for your fields() function in a closure. I can't remember if that's allowed or not.

unclecheese

function { return ['ID' => ['type' ...] ] } etc..

Anthony van Beek

mmmmm this is currently my function

  1. public function fields()
  2. {
  3. $courseConnection = Connection::create('Topics')
  4. ->setConnectionType(function () {
  5. return $this->manager->getType('Topic');
  6. })
  7. ->setDescription('A list of the Topics')
  8. ->setSortableFields(['ID', 'Title']);
  9.  
  10. return [
  11. 'ID' => ['type' => Type::nonNull(Type::id())],
  12. 'Title' => ['type' => Type::string()],
  13. 'Estimate' => ['type' => Type::string()],
  14. 'Audience' => ['type' => Type::string()],
  15. 'Content' => ['type' => Type::string()],
  16. 'Hero' => ['type' => $this->manager->getType(StaticSchema::inst()->typeName(DBFile::class))],
  17. 'URLSegment' => ['type ' => Type::string()],
  18. 'Topics' => [
  19. 'type' => $courseConnection->toType(),
  20. 'args' => $courseConnection->args(),
  21. 'resolve' => function ($object, array $args, $context) use ($courseConnection) {
  22. return $courseConnection->resolveList(
  23. $object->Topics(),
  24. $args,
  25. $context
  26. );
  27. }
  28. ]
  29. ];
  30. }
Anthony van Beek

This is what my graphql.yml file looks like :

  1. SilverStripe\GraphQL\Manager:
  2. schemas:
  3. default:
  4. types:
  5. Course: myProject\CourseTypeCreator
  6. ...
  7. mutations:
  8. ...
  9. queries:
  10. ...
  11. scaffolding:
  12. types:
  13. Page:
  14. ...
  15. myProject\Topic:
  16. ...
  17. typeNames:
  18. DNADesign\Elemental\Models\BaseElement: Block
  19. DNADesign\Elemental\Models\ElementalArea: ElementalArea
  20. myProject\Topic: Topic
  21. ...
unclecheese
  1. return function () {
  2. return [
  3. 'ID' => ['type' => Type::nonNull(Type::id())],
Anthony van Beek
  1. Error: Course fields must be an object with field names as keys or a function which returns such an object.
  2. at invariant (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:25910:12)
  3. at defineFieldMap (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26708:28)
  4. at GraphQLObjectType.getFields (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26674:45)
  5. at http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26364:28
  6. at typeMapReducer (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26376:8)
  7. at http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26374:23
  8. at Array.forEach (<anonymous>)
  9. at http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26365:30
  10. at typeMapReducer (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26376:8)
  11. at typeMapReducer (http://sorted-website.local:8080/resources/vendor/silverstripe/graphql-devtools/client/dist/graphiql.js?m=1557276366:26344:13)
unclecheese

I wonder if that registerFixedTypes needs to be abstracted out of SchemaScaffolder, since it applies to non-scaffolded schema, too.

unclecheese

it's almost like fixed_types needs to be a config property of Manager, not SchemaScaffolder.

Anthony van Beek

Well I could just scaffold the Course which worked previously

unclecheese

Is there a reason you're using the typecreator in lieu of scaffolding? I know there are many, but I'm curious what your reasoning is here, because it seems straightforward.

Anthony van Beek

I was looking at adding in my own custom fields to the graphql response.

eg. I want to calculate the progress of a course and add it as a field into the Course response

unclecheese

Computed properties work in the scaffolder, though.. getCourseProgress() can be declared as fields: { CourseProgress }

Anthony van Beek

The problem that lead me down that rabbit hole is that fields: '*' doesn’t pick up the computed properties.

unclecheese

i often wonder if we could expose those through docblocks


Show less replies
Anthony van Beek

What is the best way to get the currently logged in user in my model?

Anthony van Beek

Security::getCurrentUser(); works in dev/graphiqp but not from my SPA which uses token auth.

nils

Has anyone used extra_fields with GraphQL?

MichalKleiner

Not yet… we used custom resolvers and custom type creators, so I imagine it wouldn’t be a problem there. Not sure about the scaffolder.

nils

Yeah think you need a custom type as there's no way to define the joined fields otherwise

kinglozzer

errors: [{message: "Cannot query field "Quantity" on type "ItemsConnection".",…}] halp

kinglozzer

Here’s the GraphQL query.. I’m probably doing something stupid