I want to label images through your defined tags in meteor application.
I went through the following packages:
yogiben & meteor-simple-schema but was not able to find something concrete.
Additionally, meteor schema is using
MySchema = new SimpleSchema({
firstName: {
type: String,
label: function () {
return Session.get("lang") == "de"
? "Vorname" : "first name";
}
}
});
but I want the user to apply label dynamically.
Related
I am using Google autocomplete API in a react app. By default, the user can enter a street address or the name of a business in the autocomplete search field and google will autocomplete it. How can I restrict the autocomplete field to only autocomplete business names?
You can set the type as establishment.
Here is an example code:
let autocomplete;
function initMap() {
autocomplete = new google.maps.places.Autocomplete(
document.getElementById("autocomplete"),
{
types: ["establishment"],
componentRestrictions: { country: ["US"] },
fields: ["place_id", "geometry", "name", "formatted_address"],
}
);
autocomplete.addListener("place_changed", onPlaceChanged);
}
function onPlaceChanged() {
var place = autocomplete.getPlace();
if (!place.geometry) {
document.getElementById("autocomplete").placeholder = "Enter a place";
} else {
document.getElementById("business-name").innerHTML = place.name;
document.getElementById("full-address").innerHTML =
place.formatted_address;
}
}
For more info you can check the doc here
Say I have a post content type with the following 4 fields:
title (string)
content (string)
slug (string)
author (relationship)
How can I add a 5th field that depends on one of the above 4 fields for its value and isn't user-editable? Say, I wanted a wordCount field with the number of words in the content field as its value. What file should I consider exploring in order to incorporate this functionality?
P.S.: For what it's worth, I'm using MongoDB Atlas for my database needs.
You will have to create your wordCount attribute in your content type.
Then in the content manager link in the left menu, you will be able to custom the view of your edit/create page. Here you will be able to Disable or Remove the field from the page.
After that you will have to go in the ./api/post/models/Post.js file and update following functions.
If you are using NoSQL database (Mongo)
beforeSave: async (model) => {
if (model.content) {
model.wordCount = model.content.length;
}
},
beforeUpdate: async (model) => {
if (model.getUpdate().content) {
model.update({
wordCount: model.getUpdate().content.length
});
}
},
If you are using SQL (SQLite, Postgres, MySQL)
beforeSave: async (model, attrs, options) => {
if (attrs.content) {
attrs.wordCount = attrs.content.length;
}
},
(For Strapi 3.x; NoSQL and SQL)
Create a wordcount field on the content type
Configure the view of the content type and click on the wordcount field - set 'Editable field' to false.
Edit ./api/post/models/post.js
'use strict';
module.exports = {
lifecycles: {
async beforeCreate(data) {
data.wordcount = data.content.match(/(\w+)/g).length;
},
async beforeUpdate(params, data) {
data.wordcount = data.content.match(/(\w+)/g).length;
},
},
};
I'm having a hard time understanding when to use GraphQLInterfaceType and GraphQLUnionType.
I've RTFMs:
http://graphql.org/docs/api-reference-type-system/#graphqluniontype
https://github.com/mugli/learning-graphql/blob/master/7.%20Deep%20Dive%20into%20GraphQL%20Type%20System.md
Can anyone offer up a real world example when these would be useful to get it through my thick head?
Both are meant to help you design a schema with a heterogeneous set of types, and you could achieve the same functionality using both, but GraphQLInterfaceType is more suitable when the types are basically the same but some of the fields are different, and GraphQLUnionType when the types are totally different and have totally different fields.
Ultimately whether to use one or the other depending on your schema design.
For a real world example, let's say you have a list of blogs, but blogs using framework A use username and password as authentication, and blog using framework B use email and password. We design it with a GraphQLInterfaceType like this:
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
password: { type: new GraphQLNonNull(GraphQLString) }
},
resolveType: resolveBlogType
});
const BlogAType = new GraphQLObjectType({
name: 'BlogA',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const BlogBType = new GraphQLObjectType({
name: 'BlogB',
interfaces: [Blog],
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
function resolveBlogType(value) {
return value.username ? BlogAType : BlogBType;
}
When we create a new blog sending username, it will create a BlogA.
We can query like this:
query MyQuery {
blogs: {
url
password
... on BlogA {
email
}
... on BlogB {
username
}
}
}
Now let's get the same functionality but using GraphQLUnionType, because we prefer to use simply one type of blog, and 2 types of authentication methods:
const AuthAType = new GraphQLObjectType({
name: 'AuthA',
fields: {
username: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthBType = new GraphQLObjectType({
name: 'AuthB',
fields: {
email: { type: new GraphQLNonNull(GraphQLString) },
password: { type: new GraphQLNonNull(GraphQLString) }
}
});
const AuthType = new GraphQLUnionType({
name: 'Auth',
types: [AuthAType, AuthBType]
resolveType: resolveAuthType
});
const BlogType = new GraphQLInterfaceType({
name: 'Blog',
fields: {
url: { type: new GraphQLNonNull(GraphQLString) }
auth: { type: AuthType }
},
});
function resolveAuthType(value) {
return value.username ? AuthAType : AuthBType;
}
We can query like this:
query MyQuery {
blogs: {
url
auth {
... on AuthA {
username
password
}
... on AuthB {
email
password
}
}
}
}
As you can see in this example we achieve the same thing with the interface or the union, but one or the other might be more appropriate depending on your schema design.
For example, let's say you want to add a blog framework C that also use email and password. You would need to include another field to be able to differentiate it from blog framework B in our resolveBlogType function. Let's add the type field. In our Union example, since we only have access to the fields within the Union, you would to add type to the Union. If in the future we wanted to add another Union with same fields for multiple frameworks, we would need to add the type field there as well. Not so nice to have type duplicated multiple times in our schema. It could be a better idea to use a Interface, and have a single type field accessible at the resolveBlogType function by all the Objects using the Interface.
The sematic of GraphQLInterfaceType is like most program language's interface . and graphql add some more behaviors for it. like check if the derived class implement all the fields,dynamic resolving to derived instance.
The sematic of GraphQLUnionType is not a Union ,but something like OR.(a little bit like the flowtype's type check?)
A real world example is example in Relay => Relay's Node design .
GraphQLInterfaceType is completely unrelated to GraphQLUnionType.
I think maybe you was confused by this?
interface Node{
id: string
}
type Dog implements Node{
id: string
}
type Cat implements Node{
id: string
}
union Animal = Dog | Cat
type User{
node: Node
animal: Animal
}
If be confused by this, you should get some book of strong type language to read.(like C# or Java or something else. maybe you should have a look at Flow too, this usage Dog|Cat is a type restriction)
How to write outputFields, getFatQuery, getConfigs for create new item and update items list
Please take a look gist or live
Questions are
getFatQuery() {
return Relay.QL`
???
`;
}
getConfigs() {
return [???];
}
outputFields: {
???
},
The outputFields in your schema make up the GraphQL type CreateActivityPayload that will be generated from your schema.js file. A mutation is like a regular query, but with side effects. In outputFields you get to decide what's queryable. Since your store is the only thing in your app that can change as a result of this mutation, we can start with that.
outputFields: {
store: {
type: storeType,
resolve: () => store,
},
}
The fat query operates on these output fields. Here you tell Relay what could possibly change as a result of this mutation. Adding an activity could change the following fields:
getFatQuery() {
return Relay.QL`
fragment on CreateActivityPayload #relay(pattern: true) {
store {
activities
}
}
`;
}
Finally, the config tells Relay what to do with the query when it gets it, or even if it needs to be made at all. Here, you're looking to update a field after creating a new activity. Use the FIELDS_CHANGE config to tell Relay to update your store.
getConfigs() {
return [{
type: 'FIELDS_CHANGE',
fieldsIDs: {
store: this.props.storeId,
},
}];
}
See more: https://facebook.github.io/relay/docs/guides-mutations.html
I'm trying to use the internationalization feature of sails based on i18n.
In my controller it works well. However, I would like to setup this in my model definition.
Please see the code below:
module.exports = {
attributes: {
name:{
type:'string',
required:true,
displayName: sails.__("test")
},
....
Unfortunately it does not work. I have the error below:
displayName: sails.__("test")
^
TypeError: Object [a Sails app] has no method '__'
Would you have an idea?
Any help will be very much appreciated.
Thanks,
displayName: sails.__("test")
You are trying to invoke the internationalization function statically; that is, you're seeing the error because you're running that function the moment your .js file is require()d by node.js, and before sails has finished loading.
There are two ways you can go about solving this problem.
1. Translate the value on each query
If you'd like to store the original value of displayName, and instead internationalize it each time you query for the model, you can override toJSON().
Instead of writing custom code for every controller action that uses a particular model (including the "out of the box" blueprints), you can manipulate outgoing records by simply overriding the default toJSON function in your model.
For example:
attributes: {
name:{
type:'string',
required:true,
},
getDisplayName: function () {
return sails.__(this.name);
},
toJSON: function () {
var obj = this.toObject();
obj.displayName = sails.__(this.name);
return obj;
},
...
}
2. Translate the value before create
You can use the Waterline Lifecycle Callbacks to translate the value to a particular language before the model is saved to the databas
Sails exposes a handful of lifecycle callbacks on models that are called automatically before or after certain actions. For example, we sometimes use lifecycle callbacks for automatically encrypting a password before creating or updating an Account model.
attributes: {
name:{
type:'string',
required:true,
},
displayName: {
type: 'string'
},
...
},
beforeCreate: function (model, next) {
model.displayName = sails.__(model.name);
next();
}
This internationalized the value of displayName will now be set on your model before it is inserted into the database.
Let me know how this works out for you.
Your solution is interesting. However, my wish would be to have a display name for each properties.
module.exports = {
attributes: {
name:{
type:'string',
required:true,
displayName: "Your great name"
},
adress:{
type:'string',
required:true,
displayName: "Where do you live?"
},
....
So is there a simple or clean solution to apply sails.__( foreach properties display name of the attribute?
Thanks,