angular schema form: enum translation - angularjs

I have a select, its schema looks like this:
type: {
type: 'string',
enum: ['Event', 'BusinessEvent', 'ComedyEvent', ... ],
default: 'Event'
}
and its form def like this:
{
key: 'type',
title: $translate.instant('templates.forms.event.type'),
feedback: false
}
I'm using angular translate for the i18n. The select works flawlessly, however I haven't found a way to translate the actual items in the enum. Is there a way to do this?
I was thinking of something in the form def like this:
{
key: 'type',
title: $translate.instant('templates.forms.event.type'),
feedback: false,
showAs: function(value) {
return $translate.instant('templates.forms.event.' + value);
}
}

Related

How to properly do nested schema with mongoose in React?

I have a Class schema that looks like this:
const ClassSchema = new mongoose.Schema({
title: {
type: String,
...
},
classImageURL: {
type: String,
...
},
imageWidth: {
type: String,
...
},
imageHeight: {
type: String,
...
}
});
module.exports = mongoose.models.Class || mongoose.model("Class", ClassSchema);
And a Subject schema that looks like this:
const SubjectSchema = new mongoose.Schema({
subjectTitle: {
type: String,
...
},
subjectImageURL: {
type: String,
...
},
imageWidth: {
type: String,
...
},
imageHeight: {
type: String,
...
},
});
module.exports =
mongoose.models.Subject || mongoose.model("Subject", SubjectSchema);
On a dynamic page named [className], I am getting the data of the particular className from the database and destructured it. Now, on the class page, I want to send a post request to the database using all the fields titled in the Subject schema. But, I also want to add the class data that I got and add it to the Subject schema.
I used a state to hold all the data:
setForm({
subjectTitle: enteredSubjectTitle,
subjectImageURL: response.data.url,
imageWidth: response.data.width,
imageHeight: response.data.height,
classDetail: classDetail // this is the data I have on the particular class data
}); // I want to add
And I tried to make changes in the Subject schema like this:
classDetail: { Class }, // I added this in the last part of the schema
It results in a post error.
How can I achieve what I want to?

update one element of array inside object and return immutable state - redux [duplicate]

In React's this.state I have a property called formErrors containing the following dynamic array of objects.
[
{fieldName: 'title', valid: false},
{fieldName: 'description', valid: true},
{fieldName: 'cityId', valid: false},
{fieldName: 'hostDescription', valid: false},
]
Let's say I would need to update state's object having the fieldName cityId to the valid value of true.
What's the easiest or most common way to solve this?
I'm OK to use any of the libraries immutability-helper, immutable-js etc or ES6. I've tried and googled this for over 4 hours, and still cannot wrap my head around it. Would be extremely grateful for some help.
You can use map to iterate the data and check for the fieldName, if fieldName is cityId then you need to change the value and return a new object otherwise just return the same object.
Write it like this:
var data = [
{fieldName: 'title', valid: false},
{fieldName: 'description', valid: true},
{fieldName: 'cityId', valid: false},
{fieldName: 'hostDescription', valid: false},
]
var newData = data.map(el => {
if(el.fieldName == 'cityId')
return Object.assign({}, el, {valid:true})
return el
});
this.setState({ data: newData });
Here is a sample example - ES6
The left is the code, and the right is the output
Here is the code below
const data = [
{ fieldName: 'title', valid: false },
{ fieldName: 'description', valid: true },
{ fieldName: 'cityId', valid: false }, // old data
{ fieldName: 'hostDescription', valid: false },
]
const newData = data.map(obj => {
if(obj.fieldName === 'cityId') // check if fieldName equals to cityId
return {
...obj,
valid: true,
description: 'You can also add more values here' // Example of data extra fields
}
return obj
});
const result = { data: newData };
console.log(result);
this.setState({ data: newData });
Hope this helps,
Happy Coding!
How about immutability-helper? Works very well. You're looking for the $merge command I think.
#FellowStranger: I have one (and only one) section of my redux state that is an array of objects. I use the index in the reducer to update the correct entry:
case EMIT_DATA_TYPE_SELECT_CHANGE:
return state.map( (sigmap, index) => {
if ( index !== action.payload.index ) {
return sigmap;
} else {
return update(sigmap, {$merge: {
data_type: action.payload.value
}})
}
})
Frankly, this is kind of greasy, and I intend to change that part of my state object, but it does work... It doesn't sound like you're using redux but the tactic should be similar.
Instead of storing your values in an array, I strongly suggest using an object instead so you can easily specify which element you want to update. In the example below the key is the fieldName but it can be any unique identifier:
var fields = {
title: {
valid: false
},
description: {
valid: true
}
}
then you can use immutability-helper's update function:
var newFields = update(fields, {title: {valid: {$set: true}}})

How can I access all elements with a particular attribute in graphQL?

I have some json data in file called countryData.json structured as so:
{
"info":"success",
"stats":
[{
"id":"1",
"name":"USA",
"type":"WEST"
},
//...
I'm using graphQL to access this data. I have created an object type in the schema for countries using the following:
const CountryType = new GraphQLObjectType({
name: "Country",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
type: { type: GraphQLString },
})
});
I want to write a query that will allow me to access all of the elements of this array that have a certain "name" value(There can be multiple with the same name). I've written the following query, but it only returns the first match in the array:
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { type: { name: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
}
}
});
The "_" comes from const _ = require('lodash');
Also, how can I just get every single item in the array?
I have not recreated the code, therefore I can not check if it would be executed correctly. This is code, that should work in my opinion (without trying). If you want to return array of elements you need to implement https://lodash.com/docs/#filter. Filter will return all objects from stats, which match the argument name. This will return correctly inside resolver function, however, your schema needs adjustments to be able to return array of countries.
You need probably rewrite the arguments as follows as this is probably not correct. You can check out how queries or mutation arguments can be defined https://github.com/atherosai/express-graphql-demo/blob/feature/2-json-as-an-argument-for-graphql-mutations-and-queries/server/graphql/users/userMutations.js. I would rewrite it as follows to have argument "name"
args: { name: { type: GraphQLString } }
You need to add GraphQLList modifier, which defines, that you want to return array of CountryTypes from this query. The correct code should look something like this
const RootQuery = new GraphQLObjectType({
name:"RootQueryType",
fields:{
country: {
type: CountryType,
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.find(countryData.stats, {name: args.name});
}
},
countries: {
type: new GraphQLList(CountryType),
args: { name: { type: GraphQLString } },
resolve(parent, args){
return _.filter(countryData.stats, {name: args.name});
}
}
}
});
Now if you call query countries, you should be able to retrieve what you are expecting. I hope that it helps. If you need some further explanation, I made the article on implementing lists/arrays in GraphQL schema as I saw that many people struggle with similar issues. You can check it out here https://graphqlmastery.com/blog/graphql-list-how-to-use-arrays-in-graphql-schema
Edit: As for the question "how to retrieve every object". You can modify the code in resolver function in a way, that if the name argument is not specified you would not filter countries at all. This way you can have both cases in single query "countries".

Want to remove an escape character from output of an array

So I have an array thats being returned by a function:
console.log(join_ids)
[ '\'26c14292-a181-48bd-8344-73fa9caf65e7\'',
'\'64405c09-61d2-43ed-8b15-a99f92dff6e9\'',
'\'bdc034df-82f5-4cd8-a310-a3c3e2fe3106' ]
I was initially able to split the array using this function:
join_ids = join_ids.split(',');
I want to try and remove the backslashes from the output and this is the function I'm using:
join_ids = join_ids.replace(/\\/g, "");
console.log(typeof(join_ids));
object
I am trying to send a notification and the parameters in it are:
let message = {
app_id: `${app_id}`,
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{'field': 'tag', 'key': 'userId', 'relation': '=', 'value': `${join_ids[0]}`}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
};
The response I'm seeing is the following:
console.log(message);
{ app_id: '****************',
contents: { en: 'Yeah Buddy, Rolling Like a Big Shot!' },
filters:
[ { field: 'tag',
key: 'userId',
relation: '=',
value: '\'26c14292-a181-48bd-8344-73fa9caf65e7\'' } ],
ios_badgeType: 'Increase',
ios_badgeCount: 1 }
I want the respone to be:
value: '26c14292-a181-48bd-8344-73fa9caf65e7'
What might I be doing wrong?? Thanks!
This could be done by using a replace() with a simple regex and a tagged template literal when you're inserting the value into your message object as a template literal.
function stripEscape (strings, ...values) {
return values[0].replace(/\\`/g, '');
}
let message = {
app_id: `${app_id}`,
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{'field': 'tag', 'key': 'userId', 'relation': '=', 'value': stripEscape`${join_ids[0]}`}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
}
If you do not want to use the tagged template literal, you can chain the replace on your template literal paramter.
let message = {
app_id: `${app_id}`,
contents: {"en": "Yeah Buddy, Rolling Like a Big Shot!"},
filters: [{'field': 'tag', 'key': 'userId', 'relation': '=', 'value': `${join_ids[0].replace(/\\`/g, '')}`}],
ios_badgeType: 'Increase',
ios_badgeCount: 1
}
Hope this helps get what you were wanting, if you run into problems with it...let me know as I am still learning how to use ES6 features effectively.

Using angular-translate with formly in a select form

I'm trying to use angular-translate to translate the data from a select input on a form made formly, but I can't make it work properly.
Basically, when using angular-translate for other types of input, I would have to do something like
'templateOptions.label': '"NAME" | translate',
'templateOptions.placeholder': '"NAME" | translate'
following this pattern, I've tried to put my data like this:
"templateOptions.options": [
{
"name": "{{ 'OPT1' | translate }}",
"id": 1
},
{
"name": "{{ 'OPT2' | translate }}",
"id": 2
}
]
But that gives me nothing on the dropdown menu. Can someone give me any directions here?
The complete code can be found on the link http://output.jsbin.com/horawaqaki/
Thanks for the help!
In this case you can use $translate service inside your controller. This service can return you translated values, but it is asynchronous operation. Because of this you should add some flag in your controller in order to show form only when you receive this translations (in this example I'm going to use vm.areFieldGenerated and then show/hide form and element with ng-if).
So, basically you should pass an array of localization keys and $translate service will return you the following object:
{
'NAME': 'Name',
'OPT1': 'Working!',
'OPT2': 'Working indeed!'
}
And after that you are able to use this value to localize your field title or options.
Your function for generating fields and assigned translated values to the options will look like this:
// variable assignment
vm.env = getEnv();
vm.model = {};
vm.options = {formState: {}};
vm.areFieldsGenerated = false;
generateFields();
// function definition
function generateFields() {
$translate(['NAME', 'OPT1', 'OPT2']).then(function(translationData) {
vm.fields = [
{
key: 'item',
type: 'select',
templateOptions: {
valueProp: 'id',
labelProp: 'name',
options: [
{name:'Not working!', id: 1},
{name:'Not working indeed!', id: 2}
]
},
expressionProperties: {
'templateOptions.label': transationData['NAME'],
'templateOptions.options': [
{
name: translationData['OPT1'],
id:1
},
{
name: translationData['OPT2'],
id:2
}
]
}
}
];
vm.originalFields = angular.copy(vm.fields);
vm.areFieldsGenerated = true;
});
}
I've created working example here.
More examples with $translate on angular-translate.github.io.

Resources