I was trying to query my (postgres) db with a customizable statement built front end.
My resolver gets the built query inside the input param, but when I use the queryRaw method I get this error:
`"\nInvalid `prisma.queryRaw()` invocation:\n\n\n Raw query failed. Code: `42601`. Message: `db error: ERROR: syntax error at or near \"$1\"`"`
Is there a way to build a custom query and pass it like the input variable WITHOUT USING queryRawUnsafe to prisma? (queryRawUnsafe works fine, but well.. it's unsafe XD) Thanks <3
Here is my code.
getCars: (_parent, { input }, { prisma }) => {
if(input){
console.log(input) // --> SELECT * FROM car WHERE car."plate" ILIKE '%123%' //type String
const differentInput = '%123%'
// const result = prisma.$queryRaw`SELECT * FROM car WHERE car."plate" ILIKE '%123%'` // works
// const result = prisma.$queryRaw`SELECT * FROM car WHERE car."plate" ILIKE ${differentInput}` // works
// const result = prisma.$queryRawUnsafe(input) // works
const result = prisma.$queryRaw`${input}` // Doesn`t work
return result
}
// ... Other code
}
prisma.$queryRaw only accepts templated strings, not just strings. You can use the Prisma.sql helper to generate those templated strings to get the expected results. That might look like:
const sql = Prisma.sql`SELECT * FROM car WHERE car."plate" ILIKE '%123%'`
const result = prisma.$queryRaw`${sql}`
The queryRaw documentation mentions Prisma.sql with other examples but doesn't show any examples of what you are trying to do.
I am going to get the same value that is produced by keccak256 in solidity.
This is the code in my solidity file and I want to get the same value in the javascript file using ethers or web3.
bytes32 node = keccak256(abi.encodePacked(nodeString));
I got the same value of abi.encodePacked(nodeString)) by using ethers.utils.solidityPack.
const abiEncodedPackedString = ethers.utils.solidityPack(['string'], [nodeString]);
But when I tried ethers.utils.solidityKeccak256, the result wasn't the same as node in solidity.
const nodeInJavascript = ethers.utils.solidityKeccak256(['string], [abiEncodePackedString]);
I have also tried ethers.utils.keccak256(abiEncodePackedString) but I couldn't get the result either.
in web3 I used this and worked:
export const createCourseHash = (courseId, account) => {
const hexCourseId = web3.utils.utf8ToHex(courseId)
const courseHash = web3.utils.soliditySha3(
{ type: "bytes16", value: hexCourseId },
{ type: "address", value: account }
)
return courseHash
}
in ethers, you are passing plain string. try to convert it to hex value. in fact if you check the documentation, they are not passing plain strings:
The value MUST be data, such as:
an Array of numbers
a data hex string (e.g. "0x1234")
a Uint8Array
I have a number input that pops up a "numeric" text input in React Native.
In many locales this brings up a numeric pad with a comma for decimal separation, instead of a dot. This results in inputs like "100,1" instead of "100.1".
JavaScript's Number(value) only works with dot decimals, not commas. How can I determine the user's current format in order to properly parse the input?
This function will parse a decimal input based on the current locale, using react-native-localize:
import { getNumberFormatSettings } from "react-native-localize";
export function parseLocaleNumber(stringNumber: string) {
const { decimalSeparator, groupingSeparator } = getNumberFormatSettings();
return Number(
stringNumber
.replace(new RegExp(`\\${groupingSeparator}`, "g"), "")
.replace(new RegExp(`\\${decimalSeparator}`), "."),
);
}
For good measure, this complementary function provides toFixed functionality based on locale:
export function toFixedLocale(value: number, numDigits: number) {
const standardFixedString = value.toFixed(numDigits);
const { decimalSeparator } = getNumberFormatSettings();
if (decimalSeparator === ",") {
return standardFixedString.replace(".", ",");
} else {
return standardFixedString; // Locale matches JavaScript default
}
}
(parseLocaleNumber based on https://stackoverflow.com/a/42213804/152711)
I'm currently using the react-native-globalize library to format numbers but when using:
<FormattedNumber value={10000000} useGrouping={true} />
Which is supposed to present a result like this:
> 10,000,000
But for some but reason it doesn't seem to be working at all and the output is the number with no separators.
Anyone knows how to solve this or another library I could use? (yes I have done my google research first).
Thank you guys!
You can use the method toLocaleString() provided by Javascript.
Use it as:
getFormattedNumber = number => {
let formattedNumber = Number.parseInt(number).toLocaleString('en-IN');
return formattedNumber;
}
You may use en-US based on your region.
If the above code fails in Android, try below steps:
Goto your android/app/build.gradle file
Change line def jscFlavor = 'org.webkit:android-jsc:+' to def jscFlavor = 'org.webkit:android-jsc-intl:+'
Above solution is here: https://blog.bam.tech/developer-news/formating-numbers-in-react-native
You can use this function simply.
const numberWithComma = x => {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
When you call this function:
numberWithComma(10000000)
the result should be as follows:
10,000,000
For example:
let val = 14234523;
... ...
<Text> {numberWithComma(val)} </Text>
Result:
14,234,523
numberFormat = (value) => {
var re = '\\d(?=(\\d{' + 3 + '})+' + '\\D' + ')';
var num = value.toFixed(Math.max(0, ~~2));
var str = num.replace(new RegExp(re, 'g'), '$&' + ',');
return str;
}
Use:
numberFormat(4000)
Result:
4,000.00
I need to have a React Native TextInput component that will only allow numeric characters (0 - 9) to be entered. I can set the keyboardType to numeric which almost gets me there for input except for the period (.). However this does nothing to stop pasting non-numeric characters into the field.
What I've come up with so far is to use the OnChangeText event to look at the text entered. I remove any non-numeric characters from the text. Then put the text in a state field. Then update the TextInput through it's Value property. Code snippet below.
<TextInput
style={styles.textInput}
keyboardType = 'numeric'
onChangeText = {(text)=> this.onChanged(text)}
value = {this.state.myNumber}
/>
onTextChanged(text) {
// code to remove non-numeric characters from text
this.setState({myNumber: text})
}
This seems to work but it seems like a hack. Is there another way to do this?
Using a RegExp to replace any non digit is faster than using a for loop with a whitelist, like other answers do.
Use this for your onTextChange handler:
onChanged (text) {
this.setState({
mobile: text.replace(/[^0-9]/g, ''),
});
}
Performance test here: https://jsperf.com/removing-non-digit-characters-from-a-string
You can do it like this. It will only accept numeric values, and limit to 10 numbers as your wish.
<TextInput
style={styles.textInput}
keyboardType='numeric'
onChangeText={(text)=> this.onChanged(text)}
value={this.state.myNumber}
maxLength={10} //setting limit of input
/>
You can see the entered value by writing the following code in your page:
{this.state.myNumber}
In the onChanged() function the code look like this:
onChanged(text){
let newText = '';
let numbers = '0123456789';
for (var i=0; i < text.length; i++) {
if(numbers.indexOf(text[i]) > -1 ) {
newText = newText + text[i];
}
else {
// your call back function
alert("please enter numbers only");
}
}
this.setState({ myNumber: newText });
}
That is the correct way to do it till such a component (or attribute on the TextInput) is specifically developed.
The web has the ‘number’ type for the input element, but that is web based and react-native does not use a web view.
You could consider to create that input as a react component on it’s own (maybe call NumberInput): that’ll enable you to reuse it or maybe even open source it since you can create many TextInputs that has different value filters/checkers.
The downside to immediate correction is to ensure correct feedback is given to the user as to prevent confusion as to what happened to his value
React Native TextInput provides keyboardType props with following possible values :
default
number-pad
decimal-pad
numeric
email-address
phone-pad
so for your case you can use keyboardType='number-pad' for accepting only numbers. This doesn't include '.'
so,
<TextInput
style={styles.textInput}
keyboardType = 'number-pad'
onChangeText = {(text)=> this.onChanged(text)}
value = {this.state.myNumber}
/>
is what you have to use in your case.
for more details please refer the official doc link for TextInput :
https://facebook.github.io/react-native/docs/textinput#keyboardtype
First Solution
You can use keyboardType = 'numeric' for numeric keyboard.
<View style={styles.container}>
<Text style={styles.textStyle}>Enter Number</Text>
<TextInput
placeholder={'Enter number here'}
style={styles.paragraph}
keyboardType="numeric"
onChangeText={value => this.onTextChanged(value)}
value={this.state.number}
/>
</View>
In first case punctuation marks are included ex:- . and -
Second Solution
Use regular expression to remove punctuation marks.
onTextChanged(value) {
// code to remove non-numeric characters from text
this.setState({ number: value.replace(/[- #*;,.<>\{\}\[\]\\\/]/gi, '') });
}
Please check snack link
https://snack.expo.dev/#vishaldhanotiya/numeric-keyboard
Only allow numbers using a regular expression
<TextInput
keyboardType = 'numeric'
onChangeText = {(e)=> this.onTextChanged(e)}
value = {this.state.myNumber}
/>
onTextChanged(e) {
if (/^\d+$/.test(e.toString())) {
this.setState({ myNumber: e });
}
}
You might want to have more than one validation
<TextInput
keyboardType = 'numeric'
onChangeText = {(e)=> this.validations(e)}
value = {this.state.myNumber}
/>
numbersOnly(e) {
return /^\d+$/.test(e.toString()) ? true : false
}
notZero(e) {
return /0/.test(parseInt(e)) ? false : true
}
validations(e) {
return this.notZero(e) && this.numbersOnly(e)
? this.setState({ numColumns: parseInt(e) })
: false
}
Function to validate input:
validateInputs(text, type) {
let numreg = /^[0-9]+$/;
if (type == 'username') {
if (numreg.test(text)) {
//test ok
} else {
//test not ok
}
}
}
<TextInput
onChangeText={text => this.validateInputs(text, 'username')}
/>
I hope this is helpful.
const [text, setText] = useState('');
const onChangeText = (text) => {
if (+text) {
setText(text);
}
};
<TextInput
keyboardType="numeric"
value={text}
onChangeText={onChangeText}
/>
This should save from physical keyboards
A kind reminder to those who encountered the problem that "onChangeText" cannot change the TextInput value as expected on iOS: that is actually a bug in ReactNative and had been fixed in version 0.57.1. Refer to: https://github.com/facebook/react-native/issues/18874
if (!/^[0-9]+$/.test('YourString')) {
console.log('Enter Only Number');
} else {
console.log('Success');
}
<TextInput autoCapitalize={'none'} maxLength={10} placeholder='Mobile Number' value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>
and onChanged method :
onChanged(text){
var newText = '';
var numbers = '0123456789';
if(text.length < 1){
this.setState({ mobile: '' });
}
for (var i=0; i < text.length; i++) {
if(numbers.indexOf(text[i]) > -1 ) {
newText = newText + text[i];
}
this.setState({ mobile: newText });
}
}
I had the same problem in iOS, using the onChangeText event to update the value of the text typed by the user I was not being able to update the value of the TextInput, so the user would still see the non numeric characters that he typed.
This was because, when a non numeric character was pressed the state would not change since this.setState would be using the same number (the number that remained after removing the non numeric characters) and then the TextInput would not re render.
The only way I found to solve this was to use the keyPress event which happens before the onChangeText event, and in it, use setState to change the value of the state to another, completely different, forcing the re render when the onChangeText event was called. Not very happy with this but it worked.
Here is my other simple answer to accept only numbers in the text box using Regular Expressions.
onChanged(text){
this.setState({
myNumber: text.replace(/[^0-9]/g, '')
});
}
I wrote this function which I found to be helpful to prevent the user from being able to enter anything other than I was willing to accept. I also used keyboardType="decimal-pad" and my onChangeText={this.decimalTextChange}
decimalTextChange = (distance) =>
{
let decimalRegEx = new RegExp(/^\d*\.?\d*$/)
if (distance.length === 0 || distance === "." || distance[distance.length - 1] === "."
&& decimalRegEx.test(distance)
) {
this.setState({ distance })
} else {
const distanceRegEx = new RegExp(/^\s*-?(\d+(\.\d{ 1, 2 })?|\.\d{ 1, 2 })\s*$/)
if (distanceRegEx.test(distance)) this.setState({ distance })
}
}
The first if block is error handling for the event the user deletes all of the text, or uses a decimal point as the first character, or if they attempt to put in more than one decimal place, the second if block makes sure they can type in as many numbers as they want before the decimal place, but only up to two decimal places after the point.
Using a RegExp to replace any non digit. Take care the next code will give you the first digit he found, so if user paste a paragraph with more than one number (xx.xx) the code will give you the first number. This will help if you want something like price, not a mobile phone.
Use this for your onTextChange handler:
onChanged (text) {
this.setState({
number: text.replace(/[^(((\d)+(\.)\d)|((\d)+))]/g,'_').split("_"))[0],
});
}
You can remove non numeric characters using regex
onTextChanged (text) {
this.setState({
myNumber: text.replace(/\D/g, ''),
});
}
In case anyone is looking for solution that allows to use numeric keyboard but also validates input to allow only one decimal point then below is what I wrote to accomplish that. I also wanted to have comma(,) replaced with dot(.) as that's the way I'm saving it to database but you can remove that - it's optional.
const [decimalInput, setDecimalInput] = useState('')
const validator = /^[+-]?\d*(?:[.,]\d*)?$/;
function onNumberInputChange(text){
if (validator.test(text)){
text = text.replace(",",".") //this is optional
setDecimalInput(text);
}
else{
//this will remove the last character as it didn't succeed validation
setDecimalInput(text.substring(0, text.length - 1));
}
}
and text input component initialization like this:
<TextInput
style={{textAlign: 'center'}}
value = {decimalInput}
onChangeText={(text) => {
setDecimalInput(text);
onNumberInputChange(text);
}}
placeholder={"type decimal value here..."}
keyboardType="numeric"
placeholderTextColor="#ccc">
</TextInput>
Maybe some of you will need same approach.
I've created a component that solves this problem:
https://github.com/amirfl/react-native-num-textinput
For Decimal /Floating point number only try this
onChangeMyFloatNumber(text){
let newText = '';
let numbers = '0123456789.';
for (var i=0; i < text.length; i++) {
if(numbers.indexOf(text[i]) > -1 ) {
newText = newText + text[i];
if(text[i]=="."){
numbers = '0123456789'
}
}
else {
// your call back function
alert("please enter numbers only");
}
}
this.setState({ MyFloatNumber: newText });
}
if you add following lines then it will open number-pads only not characters-pads when you start typing:
<TextInput
placeholder="Enter Mobile No."
onChangeText={setMobileNumber}
value={mobileNumber}
keyboardType="number-pad"
maxLength={12}
/>
i think,
onChangeText((val:string) =>
isNaN(Number(val))
? val.substr(0, val.length - 1)
: val
)
// 0 > true
// 0. > true
// 0.3 > true
// - > false
// . > false
// 0.4- > false
// -1.3 > true
this code will be check "is this a not a number?" and, if last char is wrong delete last word.
If you are using hooks:
<TextInput
onChangeText={text=> setMyNumber(text?.replace(/[^0-9]/g, ''))}
....
/>
assuming the text is initialise using useState hook
const [myNumber,setMyNumber]=React.useState('');
change your key board type to numeric
<TextInput
onChangeText={this.onChangeText}
keyboardType={"numeric"}
/>
then replace dot with space
onChangeText=(value)=>{
let text = value.replace(".", '');
if (isNaN(text)) {
// Its not a number
return
}
console.log("text",text)
}