Error while migrating to SDK 1.0

Hello,

I am getting error while targetting new SDK 1.0

below is my error

│ Path: members
│ Target Type: hashicups.membersModelQ
│ Suggested Type: basetypes.ListValue

Below is my go.mod

github.com/hashicorp/terraform-plugin-framework v1.0.0
github.com/hashicorp/terraform-plugin-go v0.14.2
github.com/hashicorp/terraform-plugin-sdk/v2 v2.23.0

below is my code for resource[Create]

type orderResourceModel struct {
	ID      types.String    `tfsdk:"id"`
	Name    types.String    `tfsdk:"name"`
	Members []membersModelQ `tfsdk:"members"`
}

type membersModelQ struct {
	Name    types.String `tfsdk:"name"`
	Surname types.String `tfsdk:"surname"`
}

func (r *orderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Description: "Fetches the list of family members.",
		Attributes: map[string]schema.Attribute{
			"id": schema.StringAttribute{
				Description: "Placeholder identifier attribute.",
				Required:    true,
			},
			"name": schema.StringAttribute{
				Description: "Placeholder identifier attribute.",
				Computed:    true,
			},
			"members": schema.ListNestedAttribute{
				Description: "Placeholder identifier attribute.",
				Computed:    true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"name": schema.StringAttribute{
							Description: "Placeholder identifier attribute.",
							Computed:    true,
						},
						"surname": schema.StringAttribute{
							Description: "Placeholder identifier attribute.",
							Computed:    true,
						},
					},
				},
			},
		},
	}
}

func (r *orderResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var plan orderResourceModel
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	tflog.Debug(ctx, "[here] error in plan ")
	if resp.Diagnostics.HasError() {
		return
	}
	id := uuid.New()
	plan.Name = types.StringValue(id.String())
	// plan.Members = []membersModelQ{
	// 	{
	// 		Name:    types.StringValue("some"),
	// 		Surname: types.StringValue("some"),
	// 	},
	// }

	tflog.Debug(ctx, "[here] "+PrettyJson(plan))
	diags = resp.State.Set(ctx, plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}
}

below is my config

resource "family_adopt" "edu" {
    id = "someid"
}

output "family_adopt" {
  value = family_adopt.edu
}

Basically I am trying add list of object/s to member which is computed field and will be populated after apply.

Hope someone can help here

Thanks in advance.

Hi @anshumanpatil :wave:

I’ve not looked at this in details but at first glance I’m wondering if you see the same issue if you update orderResourceModel as follows:

type orderResourceModel struct {
	ID      types.String    `tfsdk:"id"`
	Name    types.String    `tfsdk:"name"`
	Members types.List      `tfsdk:"members"`
}

I have tried this but stuck with converting membersModelQ to types.List

Like -

plan.Members = []membersModelQNew{
		Name:    types.StringValue("s"),
		Surname: types.StringValue("p"),
	}

Error it says

cannot use (membersModelQNew literal) (value of type membersModelQNew) as basetypes.ListValue value in assignment

Could not find any proper example for - passing list of structs [which is my case]

Hi @anshumanpatil,

You should be able to use something like the following:

func (e *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"id": schema.StringAttribute{
				Required: true,
			},
			"name": schema.StringAttribute{
				Computed: true,
			},
			"members": schema.ListNestedAttribute{
				Computed: true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"name": schema.StringAttribute{
							Computed: true,
						},
						"surname": schema.StringAttribute{
							Computed: true,
						},
					},
				},
			},
		},
	}
}

type exampleResourceData struct {
	Id      types.String `tfsdk:"id"`
	Name    types.String `tfsdk:"name"`
	Members types.List   `tfsdk:"members"`
}

func (e *exampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var data exampleResourceData

	diags := req.Plan.Get(ctx, &data)
	resp.Diagnostics.Append(diags...)

	if resp.Diagnostics.HasError() {
		return
	}

	data.Members = types.ListValueMust(
		types.ObjectType{
			AttrTypes: map[string]attr.Type{
				"name":    types.StringType,
				"surname": types.StringType,
			},
		},
		[]attr.Value{
			types.ObjectValueMust(
				map[string]attr.Type{
					"name":    types.StringType,
					"surname": types.StringType,
				},
				map[string]attr.Value{
					"name":    types.StringValue("first name"),
					"surname": types.StringValue("last name"),
				},
			),
		},
	)

	diags = resp.State.Set(ctx, &data)
	resp.Diagnostics.Append(diags...)
}
1 Like

@anshumanpatil the ListValueMust() and ObjectValueMust() are used for simplicity and illustrative purposes. If there’s any possibility that these functions could panic then it would be best to use ListValue() and ObjectValue() and to handle the returned diagnostics gracefully at runtime.

1 Like

Thanks man it is really life saver…

Thanks @bendbennett , it really helped us lot

@anshumanpatil @Krishnan-Priyanshu good to hear that was helpful.

It’s also worth considering using models as described in the tutorials as this will simplify the code required in the Create function.

1 Like

@bendbennett could you explain how the usage differs from the tutorials? It looks the same to me!