Phx.gen.json update not working

hi

I am new to elixir. i used phx.gen.json to create curd create, index, show are working fine but update is not working at all

here is a code and error
controller

[code]def update(conn, %{“id” => id, “employee” => employee_params}) do
employee = Management.get_employee!(id)

with {:ok, %Employee{} = employee} <- Management.update_employee(employee, employee_params) do
  render(conn, "show.json", employee: employee)
end

end[/code]

model

schema "employees" do
    field :age, :integer
    field :fullname, :string
    field :status, :integer

    timestamps()
  end

  @doc false
  def changeset(%Employee{} = employee, attrs) do
    employee
    |> cast(attrs, [:fullname, :age, :status])
    |> validate_required([:fullname, :age, :status])
  end
end

Values i tried
‘{‘employee’=>{‘age’=>‘35’,‘fullname’=>‘ih’,‘status’=>‘1’}}’
‘{‘employee’:{‘age’:‘35’,‘fullname’:‘ih’,‘status’:‘1’}}’
{‘age’:‘35’,‘fullname’:‘ih’,‘status’:‘1’}
{‘age’=>‘35’,‘fullname’=>‘ih’,‘status’=>‘1’}
%{“age” => “35”, “fullname” => “ih”, “id” => “2”, “status” => “1”}

error

Phoenix.ActionClauseError at PUT /api/employees/2
could not find a matching corpWeb.EmployeeController.update clause to process request. This typically happens when there is a parameter mismatch but may also happen when any of the other action arguments do not match. The request parameters are:

How and where? As far as I remember semantics of an action you need to provide a PUT request submitting the fields id and employee.

i passed “id” in request http://0.0.0.0:4000/api/employees/2 with PUT
i am using postman to send request

and values in body

Can you provide us with an example body?

Have you submitted from a form? Have you done it via curl, have you done it via some JS function call, anything else?

Can you show it exactly how you submitted the request, and also please show the appropriate route!

my route
employee_path PUT /api/employees/:id CorpWeb.EmployeeController :update

request

curl -X PUT \ http://0.0.0.0:4000/api/employees/2 \ -H 'cache-control: no-cache' \ -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \ -H 'postman-token: fd2e42c7-d4ec-52e1-772d-cd0b5fa63225' \ -F 'fullname=ih' \ -F age=35 \ -F status=1

As I understand -F, you need to provide the full JSON:

curl -X PUT http://localhost:4000/api/employee/2 \
  -F 'employee={"age": "35", "fullname": "ih", "status": "1"}'
  -H …

Well, or you need to match on "age", "fullname", and "status" in your actions head…

that is working now but i am getting new error

expected params to be a :map, got: `"{'age':'35', 'fullname':'ih', 'status':'1'}"`

You need to JSON.decode it first.

What is the use case here? Is this a controller action for a JSON API? Or is it something that you’ll have an HTML form submit to?

It sort of looks like you’re doing the latter, in which case you need to be sending the same data shape a form would.

thank you very much @NobbZ
its difficult to understand when you came from php and start functional languagge

it working :wink:
first problem solved by sending
‘employee={“age”: “35”, “fullname”: “ih”, “status”: “1”}’ as json

2nd problem fixed using decoding

json = employee_params |> String.replace("'", "\"") |> Poison.decode!

I’m wondering why you need to replace singlequptes wwith double quotes when you are sending doublequotes…

Also this has nothing to do with functional vs PHP, its just how one designs his API. Multiple fields vs. a single field containing the full object.

@benwilson512 I am creating JSON API using mix phx.gen.json

I think there is little problem in generator code

anyhow it’s working now.

I’m just super confused why you’re using the formdata header type for a JSON api

@benwilson512
this request is working for me

curl -X PUT \ http://0.0.0.0:4000/api/employees/2 \ -H 'cache-control: no-cache' \ -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \ -H 'postman-token: cf8c651e-87c8-e6fe-390d-e0fc58a00741' \ -F 'employee={"age":"35", "fullname":"ih", "status":"1"}'

but when I am sending raw JSON request it’s not working from the postman

curl -X PUT \
  http://0.0.0.0:4000/api/employees/2 \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'postman-token: e6bfa4f9-bf7c-4c47-76cb-a3a46df40aa6' \
  -d 'employee={"age":"35", "fullname":"ih", "status":"1"}'

error on Request
ug.Parsers.ParseError at PUT /api/employees/2
malformed request, a Poison.SyntaxError exception was raised with message “Unexpected token at position 0: e”

@NobbZ changed request parameters to double quotes working fine now removed String.replace("’", “”")

If you put it in the body, you need to remove the employee= and submit raw JSON. But I’m not quite sure right now how you can access it then.

I’ve not yet done something with JSON in phoenix.

If you use content-type: application/json then the body needs to be actual JSON: -d '{"employee":{"age":"35", "fullname":"ih", "status":"1"}}'