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.