graphql appsync query with boolean filter - amazon-web-services

I have the need to query all incomplete projects, wherein upon completion a project will be given a status change (Completed) plus a boolean isComplete==true.
I'm working through AWS Appsync to test the queries before I hard-code them into my app, but this one doesn't seem to be effective. I want all projects where isComplete==false or isComplete==null: boolean logic doesn't work with the input1 variable below (0 results).
{"__typename":{"S":"Project"},"addressLine1":{"S":"321 Faith Cir"},"city":{"S":"Perris"},"createdAt":{"S":"2019-03-05T01:01:39.513Z"},"currentOwner":{"S":"pgres52"},"dateRequired":{"S":"2019-03-13-07:00"},"id":{"S":"89a5-42ef7efef8fb"},"status":{"S":"Created"},"statusLastChangedAt":{"S":"2019-03-05T01:01:39.513Z"}}
{
"input1":{
"isComplete": {
"ne": true
}
}
}
query listNonCompleteProjects($input1: ModelProjectFilterInput) {
listProjects(filter: $input1, limit: 20) {
items {
id
currentOwner
addressLine1
city
dateRequired
isComplete
statusLastChangedAt
}
nextToken
}
}```

Solved! Partially helped with this post: Prisma.io: How do I filter items with certain fields being null?
I was able to get it to work with an additional parameter status (string):
query listNonCompleteProjects($input1: ModelProjectFilterInput) {
listProjects(filter: $input1, limit: 20) {
items {
...
}
}
}
"input1":{
"and": [
{"status": {"notContains": "Complete"}},
{"isComplete": {
"ne": true
}}
]
},

Related

Appsync GraphQL with "None" data source trying to pass through a list of return items

I have an AppSync API that I'm using for an app. One action I'm trying to do is have a Lambda function that collects certain data fire off a GraphQL mutation, and then have a subscription on my front end collect that data when the mutation is called. This data is ephemeral and I don't want to write it to a database, so I'm trying to set up a "None" data source in AppSync just to pass this data off.
I have an AppSync GraphQL API set up with the following (simplified) schema:
type Mutation #aws_api_key
#aws_cognito_user_pools {
sendSearchResults(input: SearchResultInputHeader!): SearchResultOutputHeader
}
input SearchResultInput {
assetId: String
score: Float
}
input SearchResultInputHeader {
callId: String
results: [SearchResultInput]
}
type SearchResultOutput #aws_api_key
#aws_cognito_user_pools {
assetId: String
score: Float
}
type SearchResultOutputHeader #aws_api_key
#aws_cognito_user_pools {
callId: String
results: [SearchResultOutput]
}
and the following request / response resolver mappings:
// REQUEST::
{
"version": "2017-02-28",
"payload": {
"callId": "${context.arguments.input.callId}",
"results": "${context.arguments.input.results}"
}
}
// RESPONSE::
$util.toJson($context.result)
I am able to pass the callId String through this mutation but I am unable to get the results to pass through
// INPUT::
mutation MyMutation {
sendSearchResults(input: {resultsIn: [{assetId: "0001", score: 10}, {assetId: "0002", score: 22}], callId: "aaa-aaa-aaa"}) {
callId
resultsOut {
assetId
}
}
}
// RETURN::
{
"data": {
"sendSearchResults": {
"callId": "aaa-aaa-aaa",
"resultsOut": null
}
}
}
So I have two main questions:
How can I get the resolver/mutation to return a list of results rather than null?
Any other suggestions on passing data through an AppSync mutation and subscription? Or does this approach seem to make sense without writing to a database and just receiving a key?
Thanks!
// REQUEST::
{
"version": "2017-02-28",
"payload": {
"callId": "${context.arguments.input.callId}",
"results": "${context.arguments.input.results}"
}
}
// INPUT::
mutation MyMutation {
sendSearchResults(input: {resultsIn: [{assetId: "0001", score: 10}, {assetId: "0002", score: 22}], callId: "aaa-aaa-aaa"}) {
callId
resultsOut {
assetId
}
}
}
Here is results and resultsIn are different is two places.

how to get data from {} in graphql

I want to get data about user addinfo(bool value).
when i do console.log(data.user), i can get data.user referred to below picture.
if when i do console.log(data.user.user), it shows that user is undefined referred to below picture.
{
user(token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImI3ZTA5YmVhOTAzNzQ3ODQiLCJleHAiOjE1NjM4OTcxNzksIm9yaWdJYXQiOjE1NjM4OTY4Nzl9.QFB58dAvqIC9RBBohN1b3TdR542dBZEcXOG1MSTqAQQ") {
user {
id
addinfo
}
}
}
this code show that
{
"data": {
"user": {
"user": {
"id": "4",
"addinfo": false
}
}
}
}
I can't see the rest of your code, but if the code is fetching your users, there is a time before the request comes back where your user has not been fetched yet. It looks like your screenshot shows this. There is an undefined before the successful object.
You need to ensure that the data has come back first be checking if the data prop is truthy or some other way to check if the promise has completed yet.
ie
if (!data.user) return 'Loading...';
return (
<Switch>
...
In GraphQL I'm getting user info using e.g. below code:
async getUser(id) {
const result = await this.api.query({
query: gql(getUser),
variables: {
id,
},
});
return result.data.getUser || null;
}
I'm invoking it by:
const user = await userService.getUser(id);
and I do have access to user properties.
Maybe you're trying to get user data before they are retrieved and available?

How do you find an item in a repository by something other than id

If I have a repository with many properties and I want to find something by the non-id property, do I just find all and then return the data after a boolean comparison, or is there a better way to find by a property that's not the ID?
In loopback4, you need to use repository for this purpose. Do as below.
For case where you know there will be just one entry with value. (Unique columns)
const user = await this.userRepository.findOne({
where: {
username: 'test_admin'
}
});
For case where there can be multiple.
const user = await this.userRepository.find({
where: {
firstName: 'test admin'
}
});
For Loopback 3, here you find the documentation for querying data: https://loopback.io/doc/en/lb3/Querying-data.html
Basically, use a query filter like this:
const objects = await app.models.ModelName.find(
{
where: {
propertyName: value
}
}
)
Don't forget to define an index for the property you want to query because otherwise, the database engine will perform a full table scan.
"properties": {
"propertyName": {
"type": "string",
"index": {
"unique": true
}
},
...
}

lookback API where filter with multiple conditions

When using loopback API, is 'AND' operator redundant in 'where' filter with multiple conditions?
For example, I tested the following two queries and they return the same result:
<model>.find({ where: { <condition1>, <condition2> } });
<model>.find({ where: { and: [<condition1>, <condtion2>] } });
To be more specific, suppose this is the table content:
name value
---- -----
a 1
b 2
When I execute 'find()' using two different 'where' filters, I get the first record in both cases:
{ where: { name: 'a', value: 1 } }
{ where: { and: [ { name: 'a'}, { value: 1 } ] } }
I've read through the API documents, but didn't find what logical operator is used when there are multiple conditions.
If 'AND' is redundant as shown in my test, I prefer not using it. But I just want to make sure if this is true in general, or if it just happens to work with postgreSQL which I'm using.
This is a valid query which could only be accomplished with an and statement.
{
"where": {
"or": [
{"and": [{"classification": "adn"}, {"series": "2"}]},
{"series": "3"}
]
}
}
EDIT: https://github.com/strongloop/loopback-filters/blob/master/index.js
function matchesFilter(obj, filter) {
var where = filter.where;
var pass = true;
var keys = Object.keys(where);
keys.forEach(function(key) {
if (key === 'and' || key === 'or') {
if (Array.isArray(where[key])) {
if (key === 'and') {
pass = where[key].every(function(cond) {
return applyFilter({where: cond})(obj);
});
return pass;
}
if (key === 'or') {
pass = where[key].some(function(cond) {
return applyFilter({where: cond})(obj);
});
return pass;
}
}
}
if (!test(where[key], getValue(obj, key))) {
pass = false;
}
});
return pass;
}
It iterates through the keys of the where object where looking for failure, so it acts like an implicit and statement in your case.
EDIT 2: https://github.com/strongloop/loopback-datasource-juggler/blob/cc60ef8202092ae4ed564fc7bd5aac0dd4119e57/test/relations.test.js
The loopback datasource juggler contains tests which use the implicit and format
{PictureLink.findOne({where: {pictureId: anotherPicture.id, imageableType: 'Article'}},
{pictureId: anotherPicture.id, imageableId: article.id, imageableType: 'Article',}
But I just want to make sure if this is true in general, or if it just happens to work with postgreSQL which I'm using.
Is it true in general? No.
It appears that this is handled for PostgreSQL and MySQL (and probably other SQL databases) in SQLConnector. So, it is possible connectors not using SQLConnector (e.g MongoDB) don't support this. However, given the many examples I've seen online, I would say it's safe to assume other connectors have implemented it this way, too.

How to query all entities from InMemoryCache?

I am trying to query all entities from my apollo local cache (InMemoryCache) but without success.
Here is how I proceed.
query EntityList($limit: Int!, $offset: Int!) {
entities(
limit: $limit,
offset: $offset
) {
__typename
EntityId
}
}
With this query : no problem.
But later, I would like to query all entities from the cache and without any params.
query LocalEntityList {
entities {
EntityId
}
}
This simple code triggers an error
Can't find field entities on object (ROOT_QUERY)....
From the documentation site, I understand that I need to use cacheResolvers options on the InMemoryCache object.
But there is no example without passing an id as argument.
I think what you want is a #connection directive. This will allow you to cache your entities query without the limit/offset arguments.
query EntityList($limit: Int!, $offset: Int!) {
entities (
limit: $limit,
offset: $offset
) #connection(key: "EntityList_entities") {
__typename
EntityId
}
}
Making a successive call with the same connection should return all the entities from that key.
query LocalEntityList {
entities #connection(key: "EntityList_entities") {
EntityId
}
}