Use i18next translation hook for error messages - reactjs

So I have a form which works fine and for error messages I have created a schema file which contains errors defined like this
export const dataInputCreateSchema = yupObject({
company: yup.object().required('This field is required').nullable
})
In my component I am initializing my i18next translation variable like this const { t } = useTranslation('common'). As to show the error messages in case if user touch the textbox and does not write anything then required field error will be shown and its working like this
const companyFieldError = _.get(errors,'company', '');
_.get is a lodash method that takes in an object, path and default value.
I need to know how I can pass my translation defined in common.json file to companyFieldError? Translation in common.json is something like
"errorMessages": {
"requiredField": "This is required Field"
}
I don't want to discard my schema file but I want to provide key there and that key must get translated. Is there a way to do that?

Here are some changes I will make to support translation of errors.
Use the message in the schema definition.
export const dataInputCreateSchema = yupObject({
company: yup.object().required('errorMessages.requiredField').nullable
})
Use the message to get the translated text.
const message = _.get(errors,'company', '');
const companyFieldError = t(message);

Related

Using variables in typeScript graphQL code generator

I followed this tutorial to auto generate the schema of my graphql endpoint in my front application.
However now I need to use variables, so I did something like this:
export const GET_TODO = gql`
query GetTodo($id: Int!) {
todos(id: $id) {
id
text
completed
}
}
}
I want to know if there is a way I can get the variable type "automatically" without having to redefine it in the front.
E.g.
...
query GetTodo($id: AutoGeneratedTodoIdType) {
...
PS: I am using react, in case there are framework/library specific solutions.
Yes you can, you will usually have exported types in the generated file such as GetTodoVariables

String interpolation in gql tag

I've already posted this as an issue in the graphql-tag repositoy but I'll post it here as I hope somebody on here has a workable solution.
What am I trying to do?
I'd like to dynamically define typedefs of local types based on props passed to my react component.
Why am I doing this?
I realise this is not the intended way of defining gql, however, I'm in the process of creating a React wrapper component around the Apollo Provider. The purpose of it is to make the process of mocking out data locally (as described here https://www.apollographql.com/docs/react/development-testing/client-schema-mocking/) more seamless with less boilerplate.
I'm going for a declarative approach where the user can simply define an array of fields (name, graphQL type and optional implementation that will default to a sensible faker implementation for the graphQL type) that will make local fields available directly on the Query type as well as an array of types (name, fields and an optional nested type) which should make it possible to define arbitrary local schemas declaratively with no boilerplate.
What's the outcome at the moment?
Just to establish a baseline, the following is working just fine and allows me to run codegeneration from Apollo CLI and query the new local test field (with a #client directive) in my application
const localTypeDefs = gql`
extend type Query {
test: String
}
`;
const client = new ApolloClient({
cache: new InMemoryCache(),
uri: "https://localhost:4000/graphql",
typeDefs: localTypeDefs,
...apolloClientOptions,
});
If I change the qgl definition to look like this instead
const name = "name";
const graphQLType = "String";
const localTypeDefs = gql`
extend type Query {
${name}: ${graphQLType}
}
`;
I get the following error when running codegen Syntax Error: Expected Name, found ":". If I change the gql definition to this
const testString = "test: String";
const localTypeDefs = gql`
extend type Query {
${testString}
}
`;
I get this error Syntax Error: Expected Name, found "}". on codegen. In general, it seems like everything after the interpolated string causes the compiler to emit this error on the next character. If I include the } in the testString, I get the error Syntax Error: Expected Name, found <EOF>..
Now, If I try to change to the function syntax instead so the localTypeDefs definition looks as follows:
const testString = "test: String";
const localTypeDefs = gql(`extend type Query { ${testString} } `);
The typedef is actually generated without any error, however, the codegeneration still fails with the error GraphQLError: Cannot query field "test" on type "Query" when I query for this field. The query hasn't change at all from the working baseline I posted at the top and if I change back to that without touching anything else, the codegen no longer complains about the query.
Curiously, if I change the above back to the baseline implementation but keep the explicit function call instead of the implicit `` string as the following:
const localTypeDefs = gql(`
extend type Query {
test: String
}
`);
I still get the error GraphQLError: Cannot query field "test" on type "Query" but as soon as I change back to the base case, everything is working just fine.
I was was able to get something similar to this working for a query by wrapping an input with double quotes:
const query = gql`
mutation RegenerateAgreement {
agreementsRegenerate(input: { userId: "${userId}" }) {
agreements {
body
prompt
}
}
}
`;

Using String objects in react-native

I am working on moving all my core business logic to a model layer, which would be used across all my projects.
My project set mainly comprises of a web client-facing application built on Reactjs, few internal tools also built on Reactjs, and a mobile application built on react-native.
In my model layer, I have created custom data types to handle null/empty scenarios from backend and also to add custom format functions.
Following is the code for a string model which I have built.
/**
Author - Harkirat Saluja
Git - https://bitbucket.org/salujaharkirat/
**/
"use strict";
class CustomString {
static init (value = "") {
if (value === null) {
value = "";
}
const s = new String(value);
s.__proto__.upperCaseFormat = function () {
return this.toUpperCase();
};
return s;
}
}
export default WealthyString;
The way I invoke this is as follows:-
const firstName = WealthyString.init(firstName);
const lastName = WealthyString.init(lastName);
Now, if we see this returns a string object.
In my web project, I use this as follows in the react component, and it works nice and fine.
<span>{firstName}{" "} {lastName}</span>
But, in my react-native project, if I use it in the same way, it throws this error. Also, this error only comes when remote debugging if off and not when I am connected to chrome debugger.
<Text>{firstName}{" "} {lastName}</Text>
So, in order to resolve this for now, where strings are appended as the way shown above I have used toString(). But I was wondering is there something wrong the library or am I missing something?
Update
So looks like String objects are not working with Text in react-native at all. So to fix this I do the following:-
const SecondaryText = ({style, children}) => {
const styleCopy = addLineHeightToStyle(style, 14);
let dupChildren = children;
if (dupChildren instanceof String) {
dupChildren = dupChildren.toString();
}
return (
<ReactNative.Text
allowFontScaling={false}
style={[styles.secondaryText, styleCopy]}
>
{dupChildren}
</ReactNative.Text>
);
};
Built a wrapper over Text which react-native provides and convert the object to a string inside this.
Concatenate string using template literals in case of string combination.
Consider use template literals for complicated string. Eg:
<Text>{`${firstname} ${lastname}`}</Text>
Do you want to change this as follows?
<Text>{firstName +" "+lastName}</Text>
There are multiple ways you can do this. Write a function and return the concatenated string.
const test = (firstName ,lastName) => {
return firstName+lastName
}
If you have a class, you can do like this inside your render function.
<Text>{this.test()}</Text>

How can I do string interpolation in a string variable in React?

I have a variable coming from a static JSON file:
`const label = json.myString`
Where json.myString is "Hello, ${ name }". Since this is a variable, I do not know what it would be before hand.
And I want to do some string interpolation in my react component:
<div>{ label }</div>
How can I do this? Bonus points for a backup/default option if xyz is undefined
You should use template engine for this, for example, Mustache.
However, you can use an eval, but you don't want to use it, because it is unsafe in your case (some injections can be performed, if someone will perform a MITM-attack for your server, for example).
var a = "kappa"
console.log(eval("`Hello, ${a}!`"))
The other option that you can use is regular expressions.
There are 2 moments, that you should notice in this case:
Variables must be exist in some context, e.g. this, to allow stringified variables names be passed as key
You should not use special symbols of your template bounds inside template, or you should additionaly handle each special symbol inside regular expression.
var template = "My awesome template says: \"${ say }\""
var data = { say: "Hello!" }
console.log(template.replace(/\$\{([^}]+)\}/g, (match, group) => {
return data[group.trim()]
}))
By the way, this question is not React-specific, I suppose, but JS-specific. React doen't provide any profit features for this kind of logic tasks :)
The purpose of template literals is to avoid the usage of "some string" + "another string", and not much functionally.
In this scenario, it would be best to decouple the name with Hello.
That way, you could call
<div>Hello, ${name} </div>
In case you'd like to create a flexible greeting as well, you could then add the greeting as another string. E.g.:
{
name: "John Doe",
greeting: "Hello"
}
And go,
<div>${greeting}, ${name}</div>

DraftJS - contentState.getBlockMap is not a function

I'm trying to save editorState to DB and show back to editor. For this thing, I followed this answer
Now, when I try to get current content and permanently save it using convertToRaw, It works fine. But when I try to use this data and transform raw to contentState using convertFromRaw I get following error:
Uncaught TypeError: contentState.getBlockMap is not a function
Here is my code to convert editorState from saved state:
{
const convertedState = convertFromRaw(JSON.parse(value))
const editorValue = EditorState.createWithContent(convertedState);
}
This way, it shows data in editor but when I type something to rich editor. It prompts :
Uncaught TypeError: contentState.getBlockMap is not a function
P.s. using draft-js: '0.10.5'
EditorState is an Immutable Record that represents the entire state of a Draft.js editor, which includes the ContentState, but they are different things.
An EditorState object maintains undo and redo stacks comprised of ContentState objects.
What you are probably looking for is :
const convertedState = convertFromRaw(JSON.parse(value))
const editorValue = EditorState.createWithContent(convertedState.getCurrentContent());

Resources