Search code examples
angularhttpasp.net-coreasp.net-core-3.1http-patch

(.net core 3.1 & Angular) Json Patch: The path segment is invalid for an array index


I have a json file with the following content:

{
    "Id": 0,
    "Name": "todoList1",
    "ListItems": [
        {
            "Id": 1,
            "Description": "listItem1.1",
            "Done": false
        },
        {
            "Id": 2,
            "Description": "listItem1.2",
            "Done": true
        }
    ]
}

Additionally I have an ASP.NET Core 3.1 API method which should be able to partially update the json:

 [HttpPatch("{name}")]
    public async Task<TodoListDomainModel> Update([FromRoute] string name, [FromBody]JsonPatchDocument<TodoListDomainModel> todoListJsonPatchDocument)
    {
        var todoListToPatch = (await this._todoListService.GetTodoLists()).Single(x => x.Name == name);
        todoListJsonPatchDocument.ApplyTo(todoListToPatch);
        return todoListToPatch;
    }

The TodoListDomainModel:

public class TodoListDomainModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<ListItemDomainModel> ListItems { get; set; } = new Collection<ListItemDomainModel>();
}

The ListItemDomainModel:

public class ListItemDomainModel
{
    public ListItemDomainModel()
    {
    }

    public int Id { get; set;  }

    public string Description { get; set; }

    public bool Done { get; set; }

    public DateTime DueDate { get; set; }
}

Calling the API method via Angular

When calling the API method via angular:

save(selectedTodoList: TodoList) {
    let test = JSON.stringify(selectedTodoList.listItems);
    let json = `[{"op": "replace", "path": "/ListItems", "value": ${test} }]`;
    let url = `https://localhost:44305/todolist/${selectedTodoList.name}`;
    return this.http.patch<TodoList>(url, json);
  }

I'm not even coming to the breakpoint in the api method.

Is there something I'm doing wrong?

Thanks in advance


Solution

  • Try to compose the JSON body as JavaScript object:

    save(selectedTodoList: TodoList) {
        const body = [{
            op: "replace",
            path: "/ListItems",
            value: selectedTodoList.listItems
        }];
        let url = `https://localhost:44305/todolist/${selectedTodoList.name}`;
        return this.http.patch<TodoList>(url, body);
    }