Creating a JSON formatted post request with Angular 4 and Rails 5

Currently, I am in the process of developing an Angular application with a Rails backend. However, I seem to be encountering some difficulties when it comes to formatting the parameters hash to meet Rails' requirements. The data involves a many-to-many relationship with nested attributes in the form. In my Rails models, I have implemented the accepts_nested_attributes_for helper. While I am well aware of the format that Rails expects, there seems to be a minor discrepancy when making a POST request. Below, you will find two parameter hashes - one generated by Angular and the other expected by Rails.

The issue lies in the fact that Rails requires a deeper level of nesting within the expense_expense_categories attributes compared to what Angular produces. Personally, I find Angular's output more intuitive. My query revolves around how I can adjust the parameters in Angular to align with what Rails needs. Additionally, I am seeking insights into whether my current approach adheres to Angular's best practices.

Angular:

{
    "expense": {
        "date": "2017/4/13",
        "check_number": "132",
        "debit": "0",
        "notes": "har",
        "amount": "24",
        "payee_id": "334"
    },
    "expense_expense_categories_attributes": [{
            "expense_category_id": "59",
            "amount": 12
        },
        {
            "expense_category_id": "62",
            "amount": 11
        }
    ]
}

Expected Rails Format:

{
    "expense": {
        "date": "2017/12/12",
        "check_number": "122",
        "debit": "0",
        "notes": "har",
        "amount": "24",
        "payee_id": "334",
        "expense_expense_categories_attributes": {
            "210212312": {
                "expense_category_id": "72",
                "amount": "12"
            },
            "432323432": {
                "expense_category_id": "73",
                "amount": "12"
            }
        }
    }
}

In my Angular code...

onSubmit() method within the component:

onSubmit() {
    this.expenseService.addExpense(this.expenseForm.value)
      .subscribe(
        () => {
          this.errorMessage = '';
        },
        error =>  {
          this.errorMessage = <any>error;
        }
      );
    this.expenseForm.reset();
  }

Method for adding expense in the service file:

addExpense(expense: Expense): Observable<any> {
  let headers = new Headers({'Content-Type': 'application/json'});
  let options = new RequestOptions({headers: headers});

  return this.http.post('http://localhost:3000/expenses', expense, options)
    .map(
      (res: Response) => {
        const expenseNew: Expense = res.json();
        this.expenses.push(expenseNew);
        this.expensesChanged.next(this.expenses.slice());
      })
    .catch(this.handleError);
}

Main form snippet:

private initForm() {
    let expense_expense_categories_attributes = new FormArray([]);
    this.expenseForm = this.fb.group({
      id: '',
      date: '',
      amount: '',
      check_number: '',
      debit: '',
      payee_id: '',
      notes: '',
      expense_expense_categories_attributes: expense_expense_categories_attributes
    });
  }

FormArray segment for nested attributes:

onAddExpenseCategories() {

(<FormArray>this.expenseForm.get('expense_expense_categories_attributes')).push(
      new FormGroup({
        'expense_category_id': new FormControl(null, Validators.required),
        'amount': new FormControl(null, [
          Validators.required
        ])
      })
    );
  }

UPDATE: While I managed to resolve the issue using a regex workaround, it's not the most elegant solution. I am still on the lookout for a better alternative. If anyone has suggestions on how to efficiently format JSON objects and replace their contents without resorting to cumbersome methods like regex, please provide some guidance. Your help would be greatly appreciated.

Answer №1

Make sure to include expense_expense_categories in the wrap_parameters as shown below:

wrap_parameters :expense, include: [:expense_expense_categories_attributes]

To ensure all attributes are wrapped, explicitly list them in the wrap_parameters since only the model's attributes are wrapped by default.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

using css styles in an angular component of a web application

I am currently developing an Angular 2 application with ASP.NET WebAPI 2 to retrieve data. Instead of using ASP.NET cshtml pages, I am utilizing HTML pages to display the content. Within my application project, I have two CSS files - Bootstrap.css and Site ...

What is the best way to standardize complex nested data within the ngrx/store?

Currently, I am utilizing ngrx/store with Angular 6. Within the store, there exists a deeply nested structure which I have concerns about in terms of its organization: const state = [ { aliases: ['alias1', 'alias2'], isRequir ...

Using the typescript infer feature does not function properly when dealing with arrays

My TypeScript code is causing some unexpected results: const myObject = { foo: ['a', 'b', 'c'] } type MyType = typeof myObject.foo extends [...infer Content] ? string : boolean The type MyType is coming out as 'string ...

Error: In Typescript, it is not possible to assign the type 'false' to type 'true'

Currently, I am exploring Angular 2 and encountered a situation where I set the variable isLoading to true initially, and then switch it to false after fetching required data. However, upon executing this process, I encountered the following error message: ...

Mongoose fails to add an object to an array

I am facing an issue with my express application where comments are not being inserted into posts. Even though there are no errors displayed, the comments are not being added when posting via Postman. I have tried various solutions like this and this, but ...

I am seeking guidance on how to manually provide data to an rxjs observable. Can anyone help me with this basic question?

I am interested in using an observable to communicate "exceptional states" to different parts of my Angular application, but I am struggling to grasp their functionality. In the code snippet below, I have created an observer object and turned it into an o ...

Unable to retrieve the key value from a child object in Angular 2 when working with JSON Data

Currently, I am using Angular and attempting to extract data from the child object's key value. Here is the JSON data provided: "other_lessons": [ { "id": 290, "name": "Christmas Test #290", "course": { "id": ...

Having trouble with jQuery not loading? Learn how jquery-rails operates

Currently, I am diving into the world of jquery and ajax by watching railscasts episode 136 revise jquery & ajax. Despite putting in over 4 hours of effort, I am still unable to get past the initial hurdle. The issue seems to revolve around adding remote: ...

SvelteKit is having trouble with identifying Typescript syntax

I was working on a SvelteKit project with TypeScript (set up with Vite) and everything was running smoothly with "npm run dev". However, when I attempted to publish the app on Github Pages, an error popped up (on localhost) as I hovered over the only link ...

Sending VSCode to external functions

My primary entrypoint containing the activate() function is: extension.ts import * as vscode from "vscode"; import { subscribe } from "./eventListeners.ts"; export function activate(context: vscode.ExtensionContext) { vscode.command ...

What's the best way to set up multiple NestJS providers using information from a JSON file?

Recently diving into NestJS, I am in the process of building an application following the MVC architecture with multiple modules including: Project | +-- App.Controller +-- App.Service +-- App.Module | +-- SubModule1 | | | +-- SubModule1.C ...

Building a recursive component in Angular 2 using templates

If you want to check out the complete proof of concept, click on this link: https://plnkr.co/edit/slshjP?p=preview I am aiming to develop a straightforward tree component that empowers users to define a template for each node like so: <app-tree-editor ...

Different ways to fulfill the extends type interface requirement in TypeScript

Hey there, I'm looking to create reusable hooks for API requests. Here's the code I have so far: interface DataResponse<Data> { data: Data[]; } export const useRequestInfiniteHooks = <T extends DataResponse<T>>() => { co ...

Angular and Spring not cooperating with GET request. What's the issue?

I have been working on integrating a simple GET request to send an Object of type SearchMessage from my Spring Boot server to my Angular client application. After running the server application and verifying that the JSON content is correctly displayed at ...

How to manage multiple sockets within a single thread using ZeroMQ.js

Currently, I am in the process of setting up a service using ZeroMQ in conjunction with Node.js. Utilizing the ZeroMQ.js package for this purpose. Reference can be found in The ZeroMQ Guide, which outlines how to manage multiple sockets within a single ...

Mistakenly importing the incorrect version of Angular

While working on my Angular 1 app in typescript, I faced an issue when importing angular using the following syntax: import * as angular from 'angular'; Instead of importing angular from angular, it was being imported from angular-mocks. Thi ...

Encountered an error: When trying to install styled-components using npm, there was an issue reading properties of null, specifically 'edgesOut'

C:\Users\user\Desktop\react_sce\test1> npm i styled-components Oops! An error occurred while trying to install styled-components. It seems like there's a problem reading properties of null (specifically 'edgesOut& ...

Implementing optional default values in React props using conditional types

I have a dilemma with conditional props types When attempting to set a default value for my optional prop within the conditional type, it causes issues with the types export type ChatBase = { id: string; title: string; } type ChatCardProps = { title: ...

Setting a maximum value for a text box input in Angular for enhanced bot functionality

Currently, I am working with Angular 7 and I find myself trying to incorporate the min and max properties into a textbox. However, I seem to be encountering some difficulties in achieving this. <div> <input type='text' [(ngModel)]= ...

Strategies for Resolving Circular Dependencies in NestJS with GraphQL

Imagine having two different entities: // user.entity.ts @ObjectType() @Entity() export class User { @Field() @PrimaryGeneratedColumn('uuid') id: string; @Field() @Column({ unique: true }) username: string; @Column({ select: fals ...