Pluralization in vue i18n - vue.js

Hi i am trying to pluralize based on https://kazupon.github.io/vue-i18n/guide/pluralization.html
imageCount== 1
? $t("message.imageMessage", 1, { imageCount})
: $t("message.imageMessage", imageCount, {
imageCount
})
imageMessage: '{imageCount} image downloaded | {imageCount} images downloaded'
Problem : currently it is displaying bo the messages which should not happen,is there anything wrong in the way which i have implemented?
Codesandbox: https://codesandbox.io/s/lingering-haze-z9jzt?file=/src/components/HelloWorld.vue

From the documentation...
Your template will need to use $tc() instead of $t().
You can also improve / shorten your code somewhat by using {n} or {count} in your translation strings...
en: {
message: {
imageMessage: "{n} image downloaded | {n} images downloaded"
}
}
and in your templates
$tc("message.imageMessage", imageCount)

With vue#3 and vue-i18n#9 and Composition API, with locale key being:
{
message: {
imageMessage: "no images | 1 image downloaded | {n} images downloaded"
}
}
It's enough to do:
$t('message.imageMessage', { n: images.length })
// OR
$t('message.imageMessage', images.length)

Related

how to update file name dynametically when upload in ionic 4

hi i am using Ionic 4 with angular 7 in my project.
Currently i am facing difficulties on upload image.
File Transfer works fine with a static name like:
let options: FileUploadOptions = {
fileKey: 'file',
fileName: 'name.jpg',
headers: {}
.....
}
it working fine. but i need dynamic name. so i updated accordingly
this.temp_image_name = new Date().getTime()+'.jpg';
let options: FileUploadOptions = {
fileKey: 'file',
fileName: this.temp_image_name,
headers: {}
.....
}
but it not working and file name return empty. have any idea on this issue.
Thanks
i solved the issue in server side, before save or upload i renamed the file.
$temp = explode(".", $_FILES["file"]["name"]);
$newfilename = time() . '.' . end($temp);
$target_path = $target_path . $newfilename;
and return the newfileName to use the name for next use.
I tested the snippet just to be sure that combining a number getTime() and a string was ok, but it didn't seem to have any issues:
You are using a class level variable which may be being affected by something.
Try:
let temp_image_name = new Date().getTime()+'.jpg';
let options: FileUploadOptions = {
fileKey: 'file',
fileName: temp_image_name,
headers: {}
.....
}
It seems like you should not be using this plugin at all anyway as it is deprecated.

'TypeError: currentSubs[i] is not a function' when using ports in Elm 0.19

I am attempting to send data from Elm 0.19 to JavaScript using ports.
Edit: The problem seems to be related to running/building with elm-app
In Elm, I declare an outgoing port:
port modelToJs : Json.Encode.Value -> Cmd msg
which I use in the update function to produce a Cmd that sends a JSON encoded value to JavaScript.
In JS, I instantiate the Elm app:
const app = Elm.Main.init({
node: document.getElementById('root')
});
and register the data handler:
app.ports.modelToJs.subscribe(function dataHandler(data) {
console.log("got from Elm:" + data);
});
When modelToJs is called, the data is not sent and printed to the console. Instead, I get the following JavasScript runtime error (which Elm claims to avoid by design):
TypeError: currentSubs[i] is not a function
var value = _Json_unwrap(converter(cmdList.a));
2160 | for (var i = 0; i < currentSubs.length; i++)
2161 | {
> 2162 | currentSubs[i](value);
2163 | }
2164 | }
2165 | return init;
I have also provided a full proof of concept project on GitHub: https://github.com/mpgirro/elm0.19-ports-issue
The repo also contains an image of the error message (sry, I lack the reputation to post images)
The error appears to be in dataHandler.js. It currently contains this:
function dataHandler(data) {
console.log("got from Elm:" + data);
}
If you declare the function as export default the problem goes away:
export default function dataHandler(data) {
console.log("got from Elm:" + data);
}

react-native .toLocaleString() not working on android

Updated 2022: With hermes enabled you should be good now.
I'm using .toLocaleString() on react-native for my number output. All work on IOS but seems not working on Android. This is normal or? Do I need to use a function for the decimal?
rather than using a polyfill or an external dependency, change the JSC your android app builds with. For the newer versions of react-native add or override the following line in app/build.gradle
def jscFlavor = 'org.webkit:android-jsc-intl:+'
On newer versions of RN >0.62 you can change the JSC (JavaScriptCore) build variant to support/include ICU i18n library and necessary data allowing to use e.g. Date.toLocaleString and String.localeCompare
Replace this line in your android/app/build.gradle file
def jscFlavor = 'org.webkit:android-jsc:+'
with this line
def jscFlavor = 'org.webkit:android-jsc-intl:+'
Clean build and react-native run android
Note
This variant is about 6MiB larger per architecture than default.
So, expect your APK size to increase by about 4MB for each APK architecture build if using def enableSeparateBuildPerCPUArchitecture = true and a more bigger APK if separate build per architecture is disabled
You can use
number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
This is an issue with Javascript core used to run react native in Android and not with react native itself. To overcome this, you'll have to integrate latest javascript core into your android build or upgrade react native to 0.59.
The details are documented in JSC Android Buildscripts repo.
Now for people who would like to do the locale string formatting without needing to integrate the entire javascript core, Javascript has Internationalization API which lets you format numbers to language sensitive format. Documentation available at MDN
This API is not available in android and needs to be polyfilled using Intl
In your project root, install the Intl library
yarn add intl
And then in your project's index file (index.js) add the following code at the top of the file:
if(Platform.OS === 'android') { // only android needs polyfill
require('intl'); // import intl object
require('intl/locale-data/jsonp/en-IN'); // load the required locale details
}
After doing the above two steps, you can now get locale string anywhere in your project using
new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(10000000);
In case you need to format number for another locale code, all the locale code details are available under the intl/locale-data/jsonp/ directory. Simply require the ones you need in your index.js file.
The reason for this is very old version of JavaScriptCore used by react-native. iOS embeds own version which is why it is working fine there.
Issue still exists (some reading about where it's heading https://github.com/facebook/react-native/issues/19737)
And more info about this from Airbnb devs
https://medium.com/airbnb-engineering/react-native-at-airbnb-the-technology-dafd0b43838 (search for "JavaScriptCore inconsistencies")
(value) => {
if (typeof value === 'number') {
const [currency, cents] = (value / 100).toFixed(2).toString().split('.');
return `${currency.replace(/\B(?=(\d{3})+(?!\d))/g, '.')},${cents}`;
}
return '0,00';
}
it's more recent and lightweight, please check
First install:
yarn add #formatjs/intl-getcanonicallocales #formatjs/intl-locale #formatjs/intl-pluralrules #formatjs/intl-numberformat
Check if need polyfill
import {shouldPolyfill} from '#formatjs/intl-numberformat/should-polyfill'
if (shouldPolyfill()) {
require('#formatjs/intl-getcanonicallocales/polyfill');
require('#formatjs/intl-locale/polyfill');
require('#formatjs/intl-pluralrules/polyfill');
require('#formatjs/intl-numberformat/polyfill');
require('#formatjs/intl-numberformat/locale-data/en-US');
}
see source: https://formatjs.io/docs/polyfills/intl-numberformat/
A very easy and straight forward way is to use a polyfill:
First it needs to be installed:
npm i number-to-locale-string-polyfill
This has to be added in your code, best just outside the class/function where you want to use .toLocaleString().
require('number-to-locale-string-polyfill');
I solved this using a custom function
function numberToMoney(amount, simbol = '$', decimalCount = 2, decimal
= ".", thousands = ",") {
decimalCount = Math.abs(decimalCount)
decimalCount = isNaN(decimalCount) ? 2 : decimalCount
const negativeSign = amount < 0 ? "-" : ""
const i = parseInt(amount = Math.abs(Number(amount) ||
0).toFixed(decimalCount)).toString()
const j = (i.length > 3) ? i.length % 3 : 0
return simbol + negativeSign + (j ? i.substr(0, j) + thousands : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ?
decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "")
};
No need to install extra packages
Displaying currency values in React Native A zero dependencies solution:
const parseCurr = (value) =>
Platform.OS === 'android'
? '$' + price.toFixed(2)
: price.toLocaleString('en-US', { style: 'currency', currency:'USD' });
parseCurr(25.75) // => $25.75
A real life example (money values are multiplied by 100 for better cents precision) and converting the value to Brazilian Reais (R$)
export const getBRPrice = (price: number) => {
const parsedPrice =
( price / 100 ).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });
return Platform.OS === 'android'
? `R$${ ( price / 100 ).toFixed(2) }`
: parsedPrice;
};
// getBRPrice(450) => R$4,50
Solution: 1
Go to your android/app/build.gradle
Replace this line def jscFlavor = 'org.webkit:android-jsc:+'
with this
def jscFlavor = 'org.webkit:android-jsc-intl:+'
Stop the metro and rebuild your app.
Solution: 2
Otherwise, you can use this package https://www.npmjs.com/package/luxon
import import {DateTime} from 'luxon';
const date = DateTime.fromISO(new Date().toISOString());
const formatted = date.toLocaleString(DateTime.DATETIME_MED);
console.log(formatted);
Merging some responses from this thread, you can use this code where it is possible to customize the formatted response
const defaultOptions = {
significantDigits: 2,
thousandsSeparator: ',',
decimalSeparator: '.',
symbol: '$'
}
const currencyFormatter = (value, options) => {
if (typeof value !== 'number') value = 0.0
options = { ...defaultOptions, ...options }
value = value.toFixed(options.significantDigits)
const [currency, decimal] = value.split('.')
return `${options.symbol} ${currency.replace(
/\B(?=(\d{3})+(?!\d))/g,
options.thousandsSeparator
)}${options.decimalSeparator}${decimal}`
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
This will remove commas after decimal point
If you need two digits after the decimal and always want to round down
you can use below code.
Math.floor(1233.31231231 * 100) / 100).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
To round differently check out this resource
If these solutions don't work for you... In my case, I was using React Native with the expo web simulator and wanted to format minutes with 2 characters ie. 00, 01, ... 10, 11, etc. My solution was to check if minutes contained one character, if so, prepend a "0".
... + (date.getMinutes().toString().length == 1 ? "0" : "") + date.getMinutes().toString()

issue with c8ydevicecontrol.create

the code:
this.sendOperations = function () {
var operation = {
deviceId: '12161',
com_cumulocity_model_WebCamDevice: {
name: 'take picture',
parameters: {
duration: '5s',
quality: 'HD'
}
}
};
c8yDeviceControl.create(operation);
Result:
a new operation will be created in cumulocity server, but in the meantime, the chrome brower on which the app is runing will report some errors, although it looks like the app is still runing after that:
angular.js:9997 TypeError: Cannot read property 'match' of null
at k (deviceControl.js:267)
at wrappedCallback (angular.js:11498)
at wrappedCallback (angular.js:11498)
at angular.js:11584
at Scope.$eval (angular.js:12608)
at Scope.$digest (angular.js:12420)
at Scope.$apply (angular.js:12712)
at done (angular.js:8315)
at completeRequest (angular.js:8527)
at XMLHttpRequest.xhr.onreadystatechange (angular.js:8466)
any suggestion? Thanks
D. Chen

Error in Dojo 1.8 upgrade Error:{"message":"'registry' is undefined"}

I want to set the data in bodydiv how it possible.
Error in Dojo 1.8 upgrade Error:{"message":"'registry' is undefined"}
function setBodyData(link) {
if(!stringExists(link)) {
return;
}
dojo.xhrGet ({
url: link
,timeout: 50000
,content: {session_id:session_logout}
,handleAs:'text'
,load:function(data){
alert("data:"+dumpObj(data));
var l_object = dojo.byId('bodyDiv');
//dijit.byId('bodyDiv').innerHTML = data;
registry.byId('bodyDiv').set('content',data);
}
If understand correctly you now get the error? "'dijit.byId(...)' is null or not an object"?
Make sure the div 'bodyDiv' exists and try:
dom.byId("bodyDiv").innerHTML = data;
Of cause you must also require "dojo/dom".