Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setters for all generated models, like pre-v1.0 allowed #2883

Closed
JoeFerrucci opened this issue Mar 17, 2023 · 15 comments
Closed

Setters for all generated models, like pre-v1.0 allowed #2883

JoeFerrucci opened this issue Mar 17, 2023 · 15 comments
Labels
question Issues that have a question which should be addressed

Comments

@JoeFerrucci
Copy link

JoeFerrucci commented Mar 17, 2023

Question

Before v1.0, we were able to initialize any generated model directly using the default initializer (e.g., from a struct).
Now, some models are now generated as SelectionSets and the properties have no setters and the provided initializers are verbose and ugly; Unlike the InputObject type where it provides setters for each property, making it easy to manually construct the models.

How can we generate setters for every generated model?

@JoeFerrucci JoeFerrucci added the question Issues that have a question which should be addressed label Mar 17, 2023
@AnthonyMDev
Copy link
Contributor

This feature is nearly complete and will be in the 1.1 release coming very soon. It's being tracked in #2551. Currently you can beta test this functionality in the release/1.1 branch. We'd love you to try it out and give us your feedback!

@JoeFerrucci
Copy link
Author

JoeFerrucci commented Mar 18, 2023

That's great. Looking forward to that. What's the ETA on final release? I tried using release/1.1 branch just now but it looks like its still got some issues:

Xcode says in GraphQLExecutor.swift that it can't find reference to ApolloAPI which looks like the import at the top is if not CocoaPods, import ApolloAPI but I'm using CocoaPods; so my build fails now.

@JoeFerrucci
Copy link
Author

In the code generated files I now get stuff like this:

Screenshot 2023-03-18 at 2 25 01 PM

I've deleted and cleaned everything, so this is freshly generated.

config file fwiw:

{
  "schemaName" : "FooBar",
  "options" : {
    "cocoapodsCompatibleImportStatements" : true,
    "schemaDocumentation": "include",
  },
  "schemaDownloadConfiguration": {
      "downloadMethod": {
          "introspection": {
              "endpointURL": "my url",
              "httpMethod": {
                  "POST": {}
              },
              "includeDeprecatedInputValues": false,
              "outputFormat": "SDL"
          }
      },
      "downloadTimeout": 60,
      "headers": [],
      "outputPath": "ApolloCodegen/schema.graphqls/"
  },
  "input" : {
    "operationSearchPaths" : [
      "foobar/graphql/**/*.graphql"
    ],
    "schemaSearchPaths" : [
      "ApolloCodegen/**/*.graphqls"
    ]
  },
  "output" : {
    "testMocks" : {
      "none" : {
      }
    },
    "schemaTypes" : {
      "path" : "foobar/API",
      "moduleType" : {
        "embeddedInTarget" : {
          "name" : "foobar"
        }
      }
    },
    "operations" : {
      "inSchemaModule" : {
      }
    }
  }
}

@AnthonyMDev
Copy link
Contributor

Thanks for those reports! Looks like I made a little bug for Cocoapods users! I'll get that resolved. I am hoping to get this version out ASAP. Goal was end of this week, but I've hit a few roadblocks that I'm trying to sort out at the moment.

@JoeFerrucci
Copy link
Author

Great! Thanks for the update and glad I could help locate a CocoaPods issue. Looking forward to the new release!

@AnthonyMDev
Copy link
Contributor

@JoeFerrucci These issues should now be fixed in the release branch. Let me know if you are able to try this out successfully now!

@JoeFerrucci
Copy link
Author

JoeFerrucci commented Mar 21, 2023

@AnthonyMDev I no longer see the build error I mentioned but I still do not see the setters - they're still just computed properties.

    pod 'Apollo', :git => 'https://github.com/apollographql/apollo-ios.git', :branch => 'release/1.1', :commit => 'ae7acbd84b8ba2c499ba3105aca37d057e8feb78'
    pod 'Apollo/WebSocket',  :git => 'https://github.com/apollographql/apollo-ios.git', :branch => 'release/1.1', :commit => 'ae7acbd84b8ba2c499ba3105aca37d057e8feb78'

I see that the pods did update from 1.0.7 to 1.1.0

I regenerated the code but I'm still not seeing any setters and the data types are still SelectionSets (fwiw).

@AnthonyMDev
Copy link
Contributor

You will need to set the configuration option to generate initializers. They are not currently generated by default. I don't have documentation written for that yet, but the config options have been added to ApolloCodegenConfig.

In the apollo-codegen-configuration.json, inside the options object add:

"selectionSetInitializers" :  {
      "localCacheMutations" : true,
      "namedFragments" : true,
      "operations" : true
}

@JoeFerrucci
Copy link
Author

JoeFerrucci commented Mar 21, 2023

That will do it! 🙂 Seems to be good now. I have a long road of migration ahead of me. I need clarification on one thing:

@AnthonyMDev In pre-v1, I was allowed to pass nil values to my queries/mutations. So if a query took String? I didn't have to do anything special. In 1.x is it the case that I now have to unwrap the potentially-nil-String?? As in this example:

Pre-V1:

func doSomething(name: String?) {
  let query = SomeQuery(name: name)
  ...
}

V1.x:

func doSomething(name: String?) {
  // I now have to pass .none to indicate a nil value - is this correct?
  let query = SomeQuery(name: name ?? .none)
  ...
}

@AnthonyMDev
Copy link
Contributor

For input parameters on queries, yes this is the intended behavior in 1.0. Nullable input parameters are wrapped in a GraphQLNullable enum. There is a semantic difference between .none and .null in GraphQL and this forces you to recognize that and make a decision between the two.

See the inline documentation for GraphQLNullable for more info.

@JoeFerrucci
Copy link
Author

JoeFerrucci commented Mar 21, 2023

Yep, I read it. Just needed confirmation of my understanding. Seems like a pain 😅 but it's fine; I understand the reasoning.

@JoeFerrucci
Copy link
Author

JoeFerrucci commented Mar 21, 2023

Hi @AnthonyMDev

If you have an existing object of a SelectionSet instance and you want to modify the property directly,
like item.name = "Joe" - There are no setters for name. What's the prescribed way to update a property directly?
I use this for mocks/tests/dummy-data.
Thanks.

@JoeFerrucci
Copy link
Author

Not sure if this is a bug or not, maybe it isn't:

I have
struct ContentDetails: API.SelectionSet, Fragment { ... }
and the generated init:

public init(tags: [Tag?]? = nil) { 
  let objectType = API.Objects.ContentObject
  self.init(_dataDict: DataDict(objectType: objectType, 
    data: [
    "__typename": objectType.typename,
    "tags": tags
  ]))
}

has public var tags: [Tag?]? { __data["tags"] }
but when I try to safely-unwrap it I get a crash on
Apollo/DataDict.swift:110: Fatal error: Array<Optional<Tag>> expected list of data for entity.

Can you shed some light on this please? 🙏 thanks.

@AnthonyMDev
Copy link
Contributor

There are no setters for SelectionSet properties unless they are LocalCacheMutations only. There is a discussion around this right now here. Setters on these properties contradicts our original design intent, but I know that other users want this too. This is something @calvincestari and I need to discuss more.

Currently, for dummy data and mocks, I recommend using the TestMocks or initializing new SelectionSet models when your data changes.


This second comment looks like a bug. We're definitely still in development on 1.1, so not super surprised to see bugs here. Can you please make a new issue for this bug and I will look into it!

@AnthonyMDev
Copy link
Contributor

The bug you mentioned here is fixed in the 1.1 Beta release which is now out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issues that have a question which should be addressed
Projects
None yet
Development

No branches or pull requests

2 participants