Giter Club home page Giter Club logo

Comments (9)

martijnwalraven avatar martijnwalraven commented on May 19, 2024

As mentioned on Slack, we used to generate initializers for all permutations of optional variables, so we could differentiate between not providing a value for a variable and providing nil. Unfortunately, this led to combinatorial explosion with too many optional variables (as seen in issues like apollographql/apollo-tooling#35), so I removed that workaround.

I don't see a way to get both strict typing and the ability to pass in NSNull(). So the cleanest solution is probably to expose an initializer that takes an untyped GraphQLMap for cases like these. What do you think? So you see any alternatives?

from apollo-ios.

fruitcoder avatar fruitcoder commented on May 19, 2024

I think exposing an initializer with an untyped GraphQLMap sounds like a valid solution. As you said, you cannot support type safety and NSNull in the same initializer unless you introduce a new type wrapper. I used something like this in a previous project but it might be too cumbersome to not deal with the "real types" and it's also harder to read:

enum TriValue<T> {
  case value(v: T)
  case none
  case null
  
  var resolved: Any? {
    switch self {
    case let .value(v):
      return v
    case .none:
      return nil
    case .null:
      return NSNull()
    }
  }
}
func test(string: TriValue<String>, bool: TriValue<Bool>) {
}

from apollo-ios.

martijnwalraven avatar martijnwalraven commented on May 19, 2024

That's clever! But without language support for automatic wrapping (like you get for optionals), I agree it's too cumbersome.

I was thinking we could also expose a subscript or method to set null after construction:

var event = EventCreateInput(content: "contentId")
event["reaction"] = NSNull()
// or maybe something like:
event.nullify("reaction")

from apollo-ios.

fruitcoder avatar fruitcoder commented on May 19, 2024

This looks awesome! I like event.nullify("reaction"). I just realized I can already do event.graphQLMap["reaction"] = NSNull() so your solution is only convenience right?

from apollo-ios.

martijnwalraven avatar martijnwalraven commented on May 19, 2024

Yes, that should work. I also like nullify, and we could add it as an extension on GraphQLMapConvertible if we make graphQLMap { get set }.

from apollo-ios.

fruitcoder avatar fruitcoder commented on May 19, 2024

Would this be enough?

public protocol GraphQLMapConvertible: JSONEncodable {
  var graphQLMap: GraphQLMap { get set }
}

extension GraphQLMapConvertible {
  mutating func nullify(key: String) {
    self[key] = NSNull()
  }
  
  subscript (key: String) -> Any? {
    get {
      return graphQLMap[key]
    }
    set {
      if newValue == nil {
        graphQLMap.removeValue(forKey: key)
      } else {
        graphQLMap[key] = newValue
      }
    }
  }
}

from apollo-ios.

martijnwalraven avatar martijnwalraven commented on May 19, 2024

I think you'd want the type of the subscript to be JSONEncodable?, and I'm not sure we need the nil check to explicitly remove the value (shouldn't that happen by default when you assign nil to the map?), but otherwise it looks good!

from apollo-ios.

fruitcoder avatar fruitcoder commented on May 19, 2024

Yes and yes ;)

from apollo-ios.

martijnwalraven avatar martijnwalraven commented on May 19, 2024

@fruitcoder: Going to close this issue, because I just merged what seems like a very clean solution! The generated input objects now have properties of nested optional types when the object fields are optional. That means we can differentiate between .none and .some(.none). The default value is still nil, so .none, which translates to the field not being present in the resulting map. But you can set any optional property to .some(.none), to indicate an explicit null.

from apollo-ios.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.