Skip to content

Add field inits to FragmentTemplate instead of just DataDict inits #2551

Closed
@AmadeusK525

Description

@AmadeusK525

Feature request

Generated Fragment objects should also have init methods with the necessary strictly-typed fields from the struct instead of just having the DataDict init, just like InputObjects

Motivation

The Fragment models generally contain the necessary data for the Views and ViewModels that will consume them, so I use them directly instead of creating mirror models and converting the dto into them (since that would just bloat the code).

So we avoid this:

class ViewModel {
    let model: MyModel

    public init(model: MyModel) {
        self.model = model
    }
}

struct MyModel {
    let id: String
    let someField: Int

    public init(from dto: MyFragment) {
        self.id = dto.id
        self.someField = dto.someField
    }
}

And do something like this instead:

class ViewModel {
    let dto: MyFragment

    public init(dto: MyFragment) {
        self.dto = dto
    }
}

When implementing previews for these Views, we need some easy Mock data and we used to be able to initialize these fragments with a normal init which just took the fields as arguments. With the new generation engine, this feature has been removed and has been made available only on InputObjects, so the only way to initialize these fragments is through a DataDict, and you can see how this is cumbersome (as stated in the test docs). The official Mock architecture is also available but it's a little overkill when all we need to do is:

let viewModel = ViewModel(dto: .init(id: "0", someField: 43))

Besides, using Mocks means that they'd need to be embedded into the main target of the application, which isn't desirable since we have a separate target for testing.

Proposed solution

Investigating the source code, InputObjectTemplate has its own functions that are used to define the convenient inits, so those would need to be externalized somehow so that they'd be able to be reused in more than one place. FragmentTemplate defines the inits by calling the SelectionSetTemplate's BodyTemplate function, the inits are defined in the SelectionSetTemplate.DataFieldAndInitializerTemplate function.

I'm not sure if it's desirable to implement this convenient init in the DataFieldAndInitializerTemplate function since I don't know to what extent that would affect other templates, so a solution to that may be needed

Metadata

Metadata

Assignees

Labels

codegenIssues related to or arising from code generation

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions