Convert gql function to string with inserted variables - reactjs

I have this query defined, and use it succesfully in my app:
export const GET_TEAM = gql`
query($id: ID!) {
getTeam(id: $id) {
...CompleteTeam
}
}
${fragments.team}
`
But would like to use it for mocking purpose, and for that I need this representation:
getTeam(id: 3) {
id
name
isActivated
}
Is there any easy way to call gql with variables to accomplish?
There are suggestions how to do this with an instance of ApolloClient. But if possible I'd rather skip involvning the client as I will only mock the resulting data.

To follow up a bit here: The gql function returns a GraphQL Document AST (a parsed tree representation of the query). ASTs are much easier to work with than strings - at least when it gets more complicated.
For your question in the comment: Once you are in the AST space you can do all sorts of transforms. This can be done for example using the visitor patter. GraphQL.js also comes with a visit function that allows you to replace nodes. This code should serve as inspiration, no guarantees that it works ;)
function valueToNode(value) {
if (typeof value === 'string') {
return { kind: 'StringValue', value };
} else if (typeof value === 'number' && Number.isInteger(value)) {
// return integer value node
}
// all other value nodes...
}
visit(ast, {
VariableNode: {
enter(node) {
return valueToNode(variables[node.name.value]);
}
}
}
I am not sure if you should leave the AST space but as described in the comment you can use the printer as mentioned in the comment. Not sure if it prints things that are not documents.

Related

Would like to stop execution of code when a match is met

I created this service method in Angular JS which checks if an array of potential statuses(pendingApplications) match any of an array of set statuses(applicableStatuses). For this to work it meetsStatusCondition should return true after the first match occurs. Only 1 of the numbers in pendingApplications array needs to match and I'd like to end the execution of this function. Currently it's looping through every item in pendingApplications array
`containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.forEach(function(status) {
if (applicableStatuses.includes(status)) {
return pendingApplications.meetsStatusCondition = true;
}
});
}`
This is a limitation with .forEach, you can't break out if it like you can with a for loop
Just a regular for loop will work
for (const status of applicableStatuses){
if (applicableStatuses.includes(status)) {
pendingApplications.meetsStatusCondition = true;
break //or return if you want to exit out of the enclosing function instead of just the loop
}
}
Often when you want to short-circuit a forEach like this, what you're really looking for is another method like find() or some().
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.meetsStatusCondition = pendingApplications.some(function(status) {
return applicableStatuses.includes(status)
});
}
There is no point in using forEach (which doesn't have a breaking option) if you could just use a regular for ... of loop instead:
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
for (const status of pendingApplications) {
if (applicableStatuses.includes(status)) {
pendingApplications.meetsStatusCondition = true;
break;
}
}
}
However, even this seems a bit too complicated, you could just set meetsStatusCondition to the result of some:
containsApplicableStatus: function(pendingApplications, applicableStatuses) {
pendingApplications.meetsStatusCondition =
pendingApplications.some(status => applicableStatues.includes(status));
}
I do wonder if it makes sense to set a non-index property on your array though, maybe rethink that. This works but it's usually not something you'd expect on an array, and it will be lost if you convert that array to JSON for instance.

How to dynamically extend or compose a Yup schema

Say I have a Yup.string() to begin with.
Then, at some point, like in a loop, I wanna add required rule to it, effectively:
Yup.string().required('This field is required').
And maybe then add some .email check too.
I have tried this way but didn't seem to work:
function validationSchemaConstructor(question) {
const schema = Yup.string();
question.validation_rules.forEach(rule => {
if ("is_required" in rule) {
schema.required("Hey man nice shot");
}
});
return schema;
}
Ah my mistake- I need to assign the schema again cuz chaining in general works by returning the object again:
function validationSchemaConstructor(question) {
let schema = Yup.string();
question.validation_rules.forEach(rule => {
if ("is_required" in rule) {
schema = schema.required("Hey man nice shot"); // mistake here!
}
});
// un-comment to test dynamically adding additional rule
// schema = schema.email("email plesss");
return schema;
}
Though not sure if I should use the clone() somewhere.
Please advice if there's a better way :)

I can't unmarshal basic string from akka http stream

I am trying to consume a stream of json objects in akka-http. ( akka http version "10.0.9", akka-http-play-json version 1.10.1)
I follow examples on web but, for String I am getting:
could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromByteStringUnmarshaller[String]
and for my user defined Foo case class (for which I provided the json protocol):
could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.FromByteStringUnmarshaller[server.Foo]
This is the code that is simplified. I provide a EntityStreamingSupport.json() and for the Foo object a Json Format. I don't think I need one for String. If I don't put the asSourceOf and read a simple String object or a Foo case class object the code works. What am I missing?
package server
import akka.http.scaladsl.common.EntityStreamingSupport
import akka.http.scaladsl.server.{ Directives, Route }
import akka.http.scaladsl.model.StatusCodes
import de.heikoseeberger.akkahttpplayjson.PlayJsonSupport._
import play.api.libs.json._
case class Foo(bar: String)
class StreamingMarketDataUpload extends Directives {
implicit val jsonStreamingSupport = EntityStreamingSupport.json()
implicit val jsonFooFormat = Json.format[Foo]
lazy val routes: Route =
path("upload1") {
post {
entity(as[String]) { input =>
complete(StatusCodes.OK)
}
}
} ~ path("upload2") {
post {
// Compile error here
entity(asSourceOf[String]) { marks =>
complete(StatusCodes.OK)
}
}
} ~ path("upload3") {
post {
entity(as[Foo]) { input =>
complete(StatusCodes.OK)
}
}
} ~ path("upload4") {
post {
// Compile error here
entity(asSourceOf[Foo]) { marks =>
complete(StatusCodes.OK)
}
}
}
}
asSourceOf[T] tries to consume the incoming data as a Source[T, _]. As its method signature indicates, asSourceOf[T] takes an implicit FromByteStringUnmarshaller[T] parameter. The de.heikoseeberger.akkahttpplayjson.PlayJsonSupport utility doesn't provide an implementation of this unmarshaller (as of version 1.19.0), but it does provide the unmarshallers necessary for consuming a simple String or Foo. This is why your code works when it's not using asSourceOf.
The examples in the documentation use SprayJsonSupport, which is shipped as part of Akka HTTP. If you don't want to use SprayJsonSupport, you'll have to implement a FromByteStringUnmarshaller to use asSourceOf: the linked source code can give you an idea of how to do this.

Get the type of React components propTypes definition

Suppose the following code:
TestComponent.propTypes = {
text: React.PropTypes.string,
myEnum: React.PropTypes.oneOf(['News', 'Photos'])
};
I did the following in another file (that was using TestComponent):
if (TestComponent.propTypes.text === React.PropTypes.string) {...}
if (TestComponent.propTypes.myEnum === React.PropTypes.oneOf) {...}
Well, to my satisfaction the first if worked. But the second if never returned true. I tried to modify it to the syntax below, but it did not help.
if (TestComponent.propTypes.myEnum === React.PropTypes.oneOf(['News', 'Photos'])) {...}
So, the question is: What mechanism is there to discover the type of a prop?
I know that React tests the value of a prop against the propType to validate it. However, I need access to the 'expected type' as well to do my stuff.
BTW, here's an excerpt from the React code that validates propTypes (shortened for the sake of brevity):
function createPrimitiveTypeChecker(expectedType) {
function validate(props, propName, componentName, location, propFullName){
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== expectedType) {
// return some Error
}
return null;
}
return createChainableTypeChecker(validate);
}
As you can see the parameter of the outer function is expectedType. It is used in the inner validate function (if (propType !== expectedType)). However, React does not save the expectedType into a member variable so that it can be accessed by outside code. So how does outside code figure out the type of the propType??
My point is not to 'validate' a specific value for the prop. That gets taken care of by React very well. My point is to do some specific logic depending on the prop type, which I can't get to with types like anyOf, objectOf, shape, etc.
Any thoughts, suggestions??
Short answer, you can't compare these, because they point to different functions. When you call oneOf, it returns another function.
Explanation: The problem here is that React.PropTypes.oneOf is the function createEnumTypeChecker.
Whereas React.PropTypes.myEnum will contain the return value of calling the oneOf function - because in the propTypes definition you have to actually call oneOf().
The result of calling oneOf() is a different function, declared inside createChainableTypeChecker().
Unfortunately, your second try, won't work either because these functions are different, they're created each time you call oneOf(). See createChainableTypeChecker in ReactPropTypes.js
var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
Solution: I propose you test the names of the functions. This will prove that this is a valid React Prop type.
// returns false
React.PropTypes.oneOf(['myArr']) === React.PropTypes.oneOf(['myArr'])
// returns true
React.PropTypes.oneOf(['myArr']).name == React.PropTypes.oneOf(['myArr']).name
// this should return true in your case:
if ( TestComponent.propTypes.myEnum.name === React.PropTypes.oneOf().name )
Unfortunately, all non-primitive React propTypes use createChainableTypeChecker, and this always returns a function with the name checkType. If this name would be different for each propType, then you would be able to check which type is used. As it is now, you can't know if it's oneOf, objectOf or any of the others, including any.

Backbone.js: Best way to handle multiple nullable filter parameters

have the following function on my collection:
getFiltered: function (status, city) {
return this.filter(function (trainer) {
return ((status === null) ? trainer : trainer.get("TrainerStatusName") === status) &&
((city === null) ? trainer : trainer.get('City') === city);
});
}
What is is best way to deal with nullable params passed in i.e. if city it null then ignore filter/fetch all and if status is null then ignore filter/fetch all
The code above works, but curious about alternatives
Ok, first off, I'm a little confused by your question; the title says its about handling "nullable" parameters, but your code looks like it is dealing with "special case" parameters (specifically "all") ... except for the case of trainer being null, but I don't think that is even possible when iterating through a Backbone collection.
* * Edit * *
OP updated the question, so the above is no longer relevant. I've also updated my answer accordingly.
In any case, there's nothing at all wrong or unusual about your code; ternary operators are a standard way of handling one-off special cases. If you're looking for alternative ideas though, here's one that uses an extra function to DRY out (eliminate the duplication of) your code:
function matchesOrAll(expected, actual) {
return expected === null || expected === actual;
}
getFiltered: function (status, city) {
return this.filter(function (trainer) {
return matchesOrAll(status, trainer.get("TrainerStatusName") &&
matchesOrAll(city, trainer.get("City"));
}
* * Edit * *
Now that we're talking about null and not "all", it's worth pointing out that there is a better pattern for simpler cases of nulls/undefined. If you were just filtering cities, for instance, the code could just be:
getFiltered: function (expectedCity) {
return this.filter(function (currentCity) {
return expectedCity === (currentCity || expectedCity);
}
In other words, you could take advantage of Javascript's "truthiness", and the fact that disjunctive (ie. ||) booleans expressions return the first truthy value. This eliminates the need for a ternary, and many libraries use this pattern to fill in un-provided arguments; for instance, here's a line from jQuery that sets the "target" argument to a new object if none is provided:
target = arguments[1] || {};
Unfortunately though, when you're dealing with properties/attributes of things (eg. trainer.get('foo')) instead of just objects directly (eg. trainer), there's no good shortcut you can use (other than making a function).

Resources