Hussein Alkaf Hussein Alkaf - 2 months ago 7
React JSX Question

WebServer JSON Response change key names for Object

I'm implementing a react/redux app where I'm calling an API to fetch some data. The API is written in F# and uses Suave.io. In my back end, for some API calls, I return a DataSet (.NET Type). It includes many DataTables that have multiple columns. These Columns' names are from a database. When I fetch data from the API, Suave.io has mime type set as JSON so It takes DataSets and pass them as json objects to the view. The view has all the data correctly except for the DataTables that have their columns names set to names from the Database. As an example, if the name is "IND.APPL" then in the view it will be "inD.APPL". I have no idea why is this happening.

Call to backend to grab data:

export function loadIndicesDataAPI(data) {
return function(dispatch) {
dispatch(beginAjaxCall());
return fetch(`http://localhost:8083/indices`, {
method: 'post',
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => {
return response.json();
})
.then(dataRes => {
dispatch(loadIndicesDataSuccess(dataRes));
}).catch(error => {
dispatch(ajaxCallError(error))
throw(error);
});
};
}


Suave API code snippets:

type indicesForm = JsonProvider<""" { "data": [{ "shortName": "s", "name": "n", "symbolId": 1, "isAdded": true, "isDatabase": true, "isReturn": false }], "startdate": "2010-01-01", "enddate": "2011-01-01", "rebalance": 0, "observationAnalysis": 1 } """>

[<AutoOpen>]
module RestFul =

type RestInit = {
RefreshAPI : IndexItem [] * DateTime * DateTime * int * int -> DataSet
}

let JSON v =
let jsonSerializerSettings = new JsonSerializerSettings()
jsonSerializerSettings.ContractResolver <- new CamelCasePropertyNamesContractResolver()

JsonConvert.SerializeObject(v, jsonSerializerSettings)
|> OK
>=> Writers.setMimeType "application/json; charset=utf-8"

let fromJson<'a> json =
let indicesFormJson = indicesForm.Parse(json)
let indexItems = Array.init (indicesFormJson.Data.Length) (fun ind ->
let data = indicesFormJson.Data.[ind]
let indexItemNew = new IndexItem(data.SymbolId, data.Name, data.ShortName, data.IsReturn)
if data.IsAdded then indexItemNew.Add()
if data.IsDatabase then indexItemNew.Imported()
indexItemNew)
let startDate = indicesFormJson.Startdate
let endDate = indicesFormJson.Enddate
let rebalance = indicesFormJson.Rebalance
let observationAnalysis = indicesFormJson.ObservationAnalysis
indexItems, startDate, endDate, rebalance, observationAnalysis

let getResourceFromReq<'a> (req : HttpRequest) =
let getString rawForm =
System.Text.Encoding.UTF8.GetString(rawForm)
req.rawForm |> getString |> fromJson<'a>

let restInit resourceName resource =
let resourcePath = "/" + resourceName
path resourcePath >=> choose [
POST >=> request (getResourceFromReq >> resource.RefreshAPI >> JSON)
]


[<EntryPoint>]
let main argv =
let indicesWebPart = restInit "indices" {
RestInit.RefreshAPI = RefreshAPI
}

startWebServer defaultConfig (choose [indicesWebPart])
0


The other thing is that the column names start with a capital letter and they become lower case in the front end.

Answer

I think there are several issues here... Kind of... And I thought react/redux was for not pulling data like you do, but pushing data.

That aside: Im guessing:

jsonSerializerSettings.ContractResolver <- new CamelCasePropertyNamesContractResolver()

is the relevant one.

So by reading the doucmentation f.i. http://www.newtonsoft.com/json/help/html/contractresolver.htm I think it would be possible to choose another than CamelCasePropertyNamesContractResolver, or actually override even the naming created.

All above assuming the question was: "Why is the naming according to what I didnt bother to read up on documentation, and what else have I missed? Or something?"

Comments