I want to change my decimal in my service or client with generic solution. I'm using .Net WebApi on my service side. And I'm using React.JS with axios on my client side. I have some values about money in my data and they all come with (.) if it's decimal. For example, totalDebtAmount = 54.69$ then I want to show it 54,69$. And for example if the value is much more than 1000, my value should be seen such as 12.456,98$. Is there any way without string.replace() because I have so many pages and I don't want to use 'replace method' for my all values time after time. May I change settings of visual studio or axios library for it? You can see my sample codes and images at below.
export const GetDebtList = (SUBSCRIBER_OID_LIST,SUBSCRIBER_INFO_OID,PAYMENT_DATE,
SuccessOperation, FailedOperation) => {
return () => {
const body = { subscriberOidList: SUBSCRIBER_OID_LIST, subscriberInfoOid:SUBSCRIBER_INFO_OID,
paymentDate:PAYMENT_DATE };
axios.post('/api/GetDebtList', body)
.then(response => {
SuccessOperation({ DEBT_LIST: response.data });
})
.catch(() => {
FailedOperation({ DEBT_LIST: null })
});
}}
Here my data and GridPanel
You have to differentiate between the visual appealing of the number and the value itself.
The value must always be formatted as a floating-point number (using .)
How you display your currency, depends on the users' locality.
I would recommend using the Intl.NumberFormat API (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) or use a currency formatting library like Dinero.js (https://github.com/dinerojs/dinero.js)
Of course, you can already do the formatting on the server-side, but I would recommend doing so on the client.
const value = 54.69;
return (
<>
{new Intl.NumberFormat('en', { style: 'currency', currency: 'USD' }).format(value)}
</>
)
Related
I'm trying to get the temperature of each hour from this website: https://www.smhi.se/vader/prognoser/ortsprognoser/q/Stockholm/2673730
I'm getting the data from https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/16/lat/58/data.json. The "t" object is the temperature.
The problem I have is displaying the data for each hour in the repeater.
Here is my backend-code:
import { getJSON } from 'wix-fetch';
export async function getWeather() {
try {
const response = await getJSON('https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/16/lat/58/data.json');
console.log(response) // all data
const tempData = response.timeSeries[0].parameters[10].values[0];
return tempData // Only returns "t" - temperature
} catch (e) {
return e;
}
}
The backend part works, however the frontend doesn't.
import { getWeather } from 'backend/getSMHI.jsw'
$w.onReady(function () {
(
getWeather().then(weatherInfo => {
$w('#weatherRepeater').onItemReady(($item, itemData, index) => {
if (index > 6) {
$item('#tempText').text = itemData.timeSeries[index].parameters[1].values[0];
} else if (index === 6) {
$item('#tempText').text = itemData.timeSeries[index].parameters[0].values[0];
} else {
$item('#tempText').text = itemData.timeSeries[index].parameters[10].values[0];
} // The parameters number for "t" changes depending on the index
})
$w('#weatherRepeater').data = weatherInfo;
})
)
})
Seems like there are at least a couple of issues here.
First, you are retrieving a single number from the API and trying to put that in a repeater. From the description of what you're trying to do, it would seem that you mean to be retrieving a list of numbers, probably as an array. You probably want to do some filtering and/or mapping on the response data instead of directly accessing a single value.
Second, the data you send to a repeater must be in the proper format. Namely, it must be an array of objects, where each object has a unique _id property value (as a string). You are not doing that here. You are simply assigning it a number.
Third, and this is just an efficiency thing, you don't need to define the onItemReady inside the then(). Not that it will really make much of a difference here.
I am trying to use Google chart in React. I read the data from the database and use hook(useState) to save the data. But I can't load the google chart when I fetch the data. I guess it is Ajax problem. I have tried to copy the data that I read from console.log and paste it, it works, so it is not the data format issue.
//inistialise
const [v1, setV1] = useState(['x','sensor'],[0,0])
//define data value
const data = v1;
//define option for Chart
const options = {
title: "Box Office Earnings in First Two Weeks of Opening",
subtitle: "in millions of dollars (USD)",
interpolateNulls: true
};
//fetch data from database and change the data format
async function getAllSensorProfile(sensorIdList, sensorSubId, starttime, endtime) {
sensorIdList = JSON.stringify(sensorIdList)
await deviceService.GetTimeSeriesListBySensorIdListTimeRange(sensorIdList, sensorSubId, starttime, endtime).then(
(result) => {
var time = []
var _v1 = [['x', 'dogs']]
result.map((str) => (
str[1] = parseFloat(str[1])
))
_v1 = _v1.concat(result)
setV1(JSON.stringify(_v1))
console.log(v1)
},
error => {
console.log(error)
}
)
}
<Chart
chartType="LineChart"
data={this.state.data}
options={options}
width={"70%"}
height={"400px"}
/>
I have fixed it! OMG I had this issue for a few days but could not fix it. Now I find the problem!
So the problem is, setV1(JSON.stringfy(_v1)) is converting v1 to be a string, however, in <Chart>, data={data} only accept object, not a string.
So, I simply just change it to setV1(_v1) then it works!
I'm creating a form using Vue JS (more specifically the Vuetify library) and when clicking the 'Add' button I am trying to make it so that the user input is added to the database.
The database has 3 columns: id, type_id, value. I want to link the user input to the value column.
Note that allDesserts is an array that stores all of the items in the database. This is what I want to add to.
How can I achieve this?
Component in my form:
<v-combobox
:items="allDesserts.map(a => a.value)"
label="Project Type"
:search-input.sync="search"
>
<template v-slot:no-data>
<v-text-field
label="Add new dessert"
v-model="search"
>
</v-text-field>
<v-btn
#click="enterKey"
>Add</v-btn>
</template>
</v-combobox>
Axios request/method:
enterKey () {
axios.post('/api/desserts', {
value: 'key'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
}
My controller:
public function storeDessert(Request $request)
{
$dropdownType = new DropdownType();
$dropdownType->attribute_id = $request->input(rand(1, 10000));
$dropdownType->value = $request->input('value');
$dropdownType->save();
}
I am getting the following error:
"Illegal string offset 'id'"
I think your error is on this line.
$dropdownType->attribute_id = $request->input(rand(1, 10000));
Let say rand(1, 10000) will give you a value of 100, now you used this 100, as a key to access value in your requests which is not available.
Try to look your payload. You are just passing a data which has a key value only, this one.
{value: 'key'}
and now this line will work cause it is available in your payload.
$dropdownType->value = $request->input('value');
But not this one.
$dropdownType->attribute_id = $request->input(rand(1, 10000));
I am working on a core piece of my form functionality that finds the distance between two ZIP codes. It does find the distance accurately, but unfortunately, this Google Distance Matrix API is also searching for existing area codes, which can result in random and unnecessary mileage returns.
Currently, I can find the mileage between 64154 and 816 (19.1), but I would like to completely omit the return of any AREA CODE data.
This is the function that returns said data:
handleChange = (e) => {
const name = e.target.name
const value = e.target.value
this.setState({
[name]: value
//call back function to make sure we get the last character from the user input
}, () => {
this.getMiles(this.state.origin, this.state.destination)
})
}
getMiles = (origin, destination) => {
const {google} = this.props
let service = new google.maps.DistanceMatrixService()
console.log(origin)
console.log(destination)
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, (response, status) => {
if (status !== 'OK') {
alert('Error was: ' + status);
} else {
let originList = response.originAddresses;
let destinationList = response.destinationAddresses;
if (response.rows[0].elements[0].status === 'NOT_FOUND'){
return false
} else{
this.setState({mileage: response.rows[0].elements[0].distance.text.replace("mi", " ")})
}
}
});
}
I can't find anything in the documentation that would allow me to filter out certain address types. I have even tried to put different form limitations regarding character length, which works for the most part, but the user can still put three digits in and "space" all the way to the end of the input. This will, unfortunately, bypass my conditional and return the data for the AREA CODE because the character length that I am looking for will be fulfilled "816 ".length === 5
Well, I just ended up using a regex pattern to check to see if the string contains 5 digits that are numbers.
What this does is, it doesn't prevent the API from returning AREA CODE searches but it does prevent my mileage from calculating by constantly setting it to zero:
let fiveNumberMatch = /^[0-9]{5}$/;
<h1>{!this.state.origin.match(fiveNumberMatch) || !this.state.destination.match(fiveNumberMatch) ? this.state.mileage = 0 : this.state.mileage}</h1>
Works for now!
I'm trying to get an idea how can I force Play Scala framework form mapper to save null values in array property.
Example. Request body (print out of snippet below):
AnyContentAsJson({
"entities":["ENI","GDF Suez","Procter & Gamble"],
"entityValues":[null,"42",null]
})
Resulting value of entityValues property after binding:
List(Some(42.0))
But I want to see:
List(None, Some(42.0), None)
Code snippet of controller:
def actionX = Action {implicit request =>
println(request.body)
TaskForm.form.bindFromRequest.fold(
formWithErrors => {
BadRequest("error")
},
taskData => {
println(taskData.entityValues)
}
)
}
Form class with mapping:
case class TaskForm(entities: List[String],
entityValues: List[Option[Double]]) { }
object TaskForm {
val map = mapping(
"entities" -> list(text),
"entityValues" -> list(optional(of(doubleFormat)))
)(TaskForm.apply)(TaskForm.unapply)
val form = Form(
map
)
}
I also tried some combinations of optional and default mapping parameters, but a result is still the same.
Using 0 or any another numeric value instead of null is not a case.
Does anyone have any ideas how to implement such form behaviour?
Thanks in advance for your time and attention.
It looks like you're sending JSON to a form endpoint. While this will work for simple JSON structures, you get no control over how it is done and hence get problems like the one you're seeing.
I'd be explicit about being a JSON-endpoint, and then you can define your own Reads[Option[Double]] that works precisely how you want it to:
First, define the implicits at the Controller level; here's where we get to control the null-handling; it ends up being pretty easy:
implicit val optionalDoubleReads = new Reads[Option[Double]] {
def reads(json: JsValue) = json match {
case JsNumber(n) => JsSuccess(Some(n.toDouble))
case JsString(n) => JsSuccess(Some(n.toDouble))
case JsNull => JsSuccess(None) // The important one
case _ => JsError("error.expected.jsnumber")
}
}
implicit val taskReads = Json.reads[TaskForm]
With that done, we modify your Action to require JSON (using parse.json). The function itself remains remarkably similar to the original form-binding fold:
def actionX = Action(parse.json) { implicit request =>
println(request.body)
request.body.validate[TaskForm].fold(
jsonErrors => {
BadRequest(s"Error: $jsonErrors")
},
taskData => {
println(taskData.entityValues)
Ok(taskData.entityValues.toString)
}
)
}