Apollo - how to use cache.readFragment() on a filtered field? - apollo

I am trying to use cache.readFragment() to retrieve posts from the following cache entry:
{
...
"PublisherType:37": {
"__typename": "PublisherType",
"id": "37",
"posts({\"archived\":false,\"collection\":\"6\",\"sort\":\"-ordering\"})": {
"__typename": "PostConnection",
"totalCount": 8,
"edges": [...]
}
}
...
}
The following does not work and always returns null. I believe this is because there isn't a posts field in the cache:
const posts = cache.readFragment({
id: "PublisherType:37",
fragment: gql`
fragment PublisherPosts on PublisherType {
posts
}
`
});
​​
Is there a way I can retrieve the posts without knowing the filters?
It works fine if I change the fragment to:
fragment PublisherPosts on PublisherType {
posts(archived:false, collection:6, sort: "-ordering")
}
Is there a way I can query this data without having to know which filters are used? Something like posts* or even posts(*) (tried both BTW).

Related

How to properly set an API call in QML using XMLHttpRequest

I am building a small weather API as exercise to use QML and properly operate an API call using OpenWeather and you can see there a typical API response.
The problem I am having is that I can't get the API call to work. After setting a minimal example with some cities that you can see below, right next to the city it should appear the symbol of the weather, but it does not happen. The list of the icon can be found here. Source code of the MVE can be found here for completeness.
The error from the compiler: qrc:/main.qml:282: SyntaxError: JSON.parse: Parse error
This is what is happening
This is what is expected
Typical API JSON response can be found both here and below:
{
"coord": {
"lon": -122.08,
"lat": 37.39
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 282.55,
"feels_like": 281.86,
"temp_min": 280.37,
"temp_max": 284.26,
"pressure": 1023,
"humidity": 100
},
"visibility": 16093,
"wind": {
"speed": 1.5,
"deg": 350
},
"clouds": {
"all": 1
},
"dt": 1560350645,
"sys": {
"type": 1,
"id": 5122,
"message": 0.0139,
"country": "US",
"sunrise": 1560343627,
"sunset": 1560396563
},
"timezone": -25200,
"id": 420006353,
"name": "Mountain View",
"cod": 200
}
Below a snippet of code related to the API call:
main.qml
// Create the API getcondition to get JSON data of weather
function getCondition(location, index) {
var res
var url = "api.openweathermap.org/data/2.5/weather?id={city id}&appid={your api key}"
var doc = new XMLHttpRequest()
// parse JSON data and put code result into codeList
doc.onreadystatechange = function() {
if(doc.readyState === XMLHttpRequest.DONE) {
res = doc.responseText
// parse data
var obj = JSON.parse(res) // <-- Error Here
if(typeof(obj) == 'object') {
if(obj.hasOwnProperty('query')) {
var ch = onj.query.results.channel
var item = ch.item
codeList[index] = item.condition["code"]
}
}
}
}
doc.open('GET', url, true)
doc.send()
}
In order to solve this problem I consulted several sources, first of all : official documentation and the related function. I believe it is correctly set, but I added the reference for completeness.
Also I came across this one which explained how to simply apply XMLHttpRequest.
Also I dug more into the problem to find a solution and also consulted this one which also explained how to apply the JSON parsing function. But still something is not correct.
Thanks for pointing in the right direction for solving this problem.
Below the answer to my question. I was not reading properly the JSON file and after console logging the problem the solution is below. code was correct from beginning, only the response needed to be reviewed properly and in great detail being the JSON response a bit confusing:
function getCondition() {
var request = new XMLHttpRequest()
request.open('GET', 'http://api.openweathermap.org/data/2.5/weather?q=London&units=metric&appid=key', true);
request.onreadystatechange = function() {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status && request.status === 200) {
console.log("response", request.responseText)
var result = JSON.parse(request.responseText)
} else {
console.log("HTTP:", request.status, request.statusText)
}
}
}
request.send()
}
Hope that helps!
In your code, your url shows this: "api.openweathermap.org/data/2.5/weather?id={city id}&appid={your api key}". You need to replace {city id} and {your api key} with real values.
You can solve it by providing an actual city ID and API key in your request URL

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
}
},
...
}

graphql appsync query with boolean filter

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
}}
]
},

Why does this MapReduce mapping function emit not work?

I have a Cloudant database with documents that use the following format:
{
"_id": "0ea1ac7d5ef28860abc7030444515c4c",
"_rev": "1-362058dda0b8680a818b38e9c68c5389",
"text": "text-data",
"time-data": 1452988105,
"time-text": "3:48 PM - 16 Jan 2016",
"link": "http://url/to/website"
}
I'm trying to create a view to easily count documents between a start and end time-data. However, this mapping function results in a query returning "No Documents Found":
function (doc) {
emit(doc.time-data, 1);
}
... while this does:
function (doc) {
emit(doc._id, 1);
}
Why is this the case?
The issue is with the name of your field. It contains a dash: -
Javascript interprets this as:
return doc.time - data
return doc.time minus data
You can either change your property (to something like time_data), or you can create your view like this:
function (doc) {
if (doc['time-data']) {
emit(doc['time-data'], 1);
}
}