Code Monkey home page Code Monkey logo

ember-apollo-client's People

Contributors

alexking avatar anehx avatar arkadiyk avatar balaf avatar balinterdi avatar benkingcode avatar bertdeblock avatar bgentry avatar buschtoens avatar chadian avatar csantero avatar dependabot-support avatar dependabot[bot] avatar dfreeman avatar dmzza avatar fabhof avatar jasonmit avatar johanrd avatar josemarluedke avatar knownasilya avatar kobsy avatar lstrzebinczyk avatar mydea avatar n1ru4l avatar sdahlbac avatar sebastianseilund avatar terminalstar avatar venkatd avatar villander avatar viniciussbs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-apollo-client's Issues

switch to ember-common-tags

I released an ember-common-tags addon. This should remove the need for browserify in this addon's dev dependencies, and will clean up imports (i.e. import { stripIndent } from 'common-tags' instead of npm:common-tags w/ manual destructuring).

It should be super easy to switch over this addon and remove all traces of the old way. Anybody from the community want to take a crack at it to get on the contributor list? 🙏

Resolved data from mutate function doesn't include __typename

I came across this issue but it seems like the resolution in #44 doesn't apply to the data .mutate resolves to.

So if you've got something like this (using ember-concurrency, hence the yield):

const response = yield this.get('apollo').mutate({
  mutation,
  variables
});

response.__typename is undefined.

I've come across the problem because I'm trying to ensure consistency with data in ember-data and want to use store.push to do so, for which you need to pass the model type.

As suggested in the previous issue, I can use typename: __typename in the graphql declaration as a workaround, but was wondering if it's an intentional inconsistency that mutate still uses Ember.copy rather than copyWithExtras?

Tracking Apollo errors globally

Is anyone tracking Apollo errors successfully? I have tried this on an instance-initializer but the event handler is never called. It's like the error event is never triggered:

RSVP.on('error', function(error, label) {
  let message = label || error.message || 'Unknown Async Error';

  errorTrackingService.error(message, error);
});

Upgrade to Ember v3.0

This addon could use an upgrade to the latest Ember version. That would ideally include a conversion of its tests to the new async style.

_apolloUnsubscribe issue

Hi.
I'm new to this ember-apollo-client addon. I'm following the Usage instructions. Already imported the UnsubscribeRoute on route file but still getting this error Uncaught TypeError: Cannot set property '_apolloUnsubscribe' of undefined

What did I missed on this and how to fix?

And also for this example:

query human($id: String!) {
  human(id: $id) {
    name
  }
}

Does it also requires a app/models/human.js for this?

Thanks,
Rexon

Easy setup/helper for acceptance tests

@bgentry what you think about we have a setup for acceptance test with tests helpers using pretender and apollo-client?

it would be something like that

import { test } from 'qunit';
import moduleForAcceptance from 'my-app/tests/helpers/module-for-acceptance';

// Import necessary for setup
import { addResolveFunctionsToSchema } from 'graphql-tools';
import { startPretender } from '../helpers/vzon-core/test-helpers';
import schemaString from '../fixtures/test-schema.graphql'; // your schema

moduleForAcceptance('Acceptance | login', {
  beforeEach() {
    this.pretender = startPretender(schemaString);
  },
  afterEach() {
    if (this.pretender) {
      this.pretender.shutdown();
    }
  }
});

test('visiting /login', function(assert) {
  visit('/login');

  andThen(() => {
    assert.equal(currentURL(), '/login');
  });

  addResolveFunctionsToSchema(this.pretender.schema, {
    Mutation: {
      login(_, args) {
        let { input } = args;
        if (args.input.email === '[email protected]' && input.password === 'brown') {
          return {
             errors: null,
             session: {
                token: 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9',
                 __typename: 'Session'
             },
             __typename: 'LoginPayload'
          };
       }
      }
    }
  });

  fillIn('.test-email-field', username);
  fillIn('.test-password-field', password);
  click('.test-btn-login');

  andThen(() => {
    assert.equal(
      currentURL(),
      '/secret',
      'after we login, the secret route is available'
    );
  });
  
});

Need to inject `config:environment` into all unit tests that touch Apollo

Follow-up from #53.

It's a bit annoying to have to use a needs: ['config:environment'] in addition to already needing a service:apollo in any unit test that touches Apollo. As of now, this blows up on the config.apollo call when not using that injection because config is undefined here.

One way I'm working around this in my own tests is with this hack:

// used in environments without injected `config:environment` (i.e. unit tests):
const defaultOptions = {
  apiURL: "http://testserver.example/v1/graph",
};

export default ApolloService.extend({
  options: computed(function() {
    let config = getOwner(this).resolveRegistration("config:environment");
    if (config && config.apollo) {
      return config.apollo;
    } else if (testing) {
      return defaultOptions;
    }
    throw new Error("no Apollo service options defined");
  }),
  // ...
});

I'm not sure if there's a better way to handle this. At the very least, I think there should be a descriptive error like this when a required config isn't set up or available.

Cannot find module 'graphql-tag'

Hey 👋

After installing the addon and running ember server I get the following error:

Cannot find module 'graphql-tag'
Error: Cannot find module 'graphql-tag'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/willrax/Code/phoenix/node_modules/ember-apollo-client/lib/graphql-filter.js:4:13)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)

I'm running the following:

ember-cli: 2.12.2
node: 8.7.0
os: darwin x64

I can't spot anything in the readme that i might have missed. Any ideas on what I could be missing?

Various and Sundries Questions

Hey there!

I'd like to start off by saying that this looks to be the most feature complete, maintained Apollo integration for Ember, so thank you very much for this!

I am writing a tutorial for How To GraphQL on building a simple HackerNews clone using Ember+Apollo, and I am using this integration. Unfortunately, I do have a few questions. I'd love to join a Slack channel, Discord channel, or whatever where I can stay in contact if that is available. In the case that it isn't, I'll include some questions below:

  1. Where is the suggested location for adding the gql/queries folder, and what is the suggested import for a single query in that queries folder? I only ask these questions because I have been unable to get it to work. I sidestepped this by importing gql from graphql-tag and wrote the query in-line, which works perfectly.

  2. Any news on subscriptions and pagination? I'd love to include these in the tutorial, but the best answer I can find (after looking through outstanding issues) seems to be that it is a WIP. I'm completely fine noting this in my tutorial, and already have approval to do that. If that were to happen, I'd love to keep in touch and continually update the tutorial when updates are released to this wonderful integration.

  3. What are the implications of not using the UnsubscribeRoute mixin? I ask because I would prefer not to use and explain it in the tutorial if the performance loss is minimal. An alternative question is how you can explicitly use query instead of watchQuery?

  4. Are the error and loading states that Apollo returns available? I'd love to easily show a "Loading..." message or error message if they are available.

I might have some more questions, but for now, that is all. Thanks so much for this fine integration!

Add support for apollo-link-batch-http

We'd like to use apollo-link-batch-http in our app as it seems like it'd work well with Ember Routes and reducing requests as our app loads.

Obviously, this will by default mean it's included in the vendor bundle even if you don't use it, so before we go and add a PR for this, I thought I'd throw out the idea of adding some build time configuration to specify which packages from Apollo are included?

Update model after a mutation with `refetchQueries` option

The problem

Let's say that I have a list of users:

model() {
  let query = this.get('query'); // query UserList { ... }

  return this.get('apollo').query({ query, fetchPolicy: 'network-only' }).then((data) => {
    return data.usersConnection.edges.mapBy('node'); // I'm using Relay here
  });
}

And a action to delete a user from the list:

actions: {
  delete(id) {
    let mutation = this.get('deleteMutation');
    let variables = { id };

    return this.get('apollo').mutate({ query, variables, refetchQueries: ['UserList'] });
  }
}

I would like to update my list of users after the mutation. Apollo already refetches the UserList query, but the model is not updated with the recent content - the observer created by the query call doesn't know that the current model needs to be updated.

Current solution

Today I rely on my this.get('apollo.client').watchQuery so I can create my own observer that knows what to do with new data. But I need to write my own code to cleanup the subscriptions and to handle the deeply frozen result data.

Proposal

Taking a look at #20, it does not solve this problem. I can't create my own observer since managedWatchQuery does not return the observable query. Instead, it does something similar to query but with the observable queries and subscriptions being managed by the new query manager.

I think I should be able to write my own observer that knows how to update my model. Sometimes I would like to call this.get('controller.model').setObjects(newUserList) to change the list. Sometimes I would like to just append new data to the current list calling this.get('controller.model').pushObjects(moreUsers). With the addon doing the cleanup and giving me an abstraction to handle the deeply frozen result data.

Demo app

We need of demo/dummy app as ember-power-select, so we will have a case, besides making better the experience of each user that uses this addon with docs, cookbook and others

Apollo service is initializes during integration test without its options

So, the base-query-manager mixin, during the #20 development, was using a query manager got with owner.lookup. The Apollo service was not injected by the mixin.

Today the query manager is got from the Apollo service, that's always injected by the mixin. This is causing an error on integration tests because now the service initializes during the test, but the initializer that injects the options into the service doesn't run during the test. Then Apollo client raises an error saying that the network layer needs an endpoint.

How are you handling this? Are you writing integration tests?

Improved unsubscribe design

I was discussing this issue with @viniciussbs on Slack the other day. Opening an issue to solicit ideas.

With Apollo Client, after performing a watchQuery, you get back an “observable” object. The ember-apollo-client Apollo service then "subscribes" to this observable, and the resulting subscription later needs to be unsubscribed from when you no longer want it to get updated w/ new data from the store. Typically this is done when you exit a route, or when the component is being destroyed. My initial version of this addon used an ugly hack to enable this, by exposing an _apolloUnsubscribe function on the returned data and making the user responsible for calling it.

@viniciussbs and I are both unhappy with the current way that ember-apollo-client puts the onus on the user to unsubscribe from watched data whenever they're done w/ it. I’m trying to come up with a more user-friendly design that still meshes well w/ Ember.

One idea I had is that instead of injecting the apollo service directly into routes/components, you’d use some sort of mixin that would function as a proxy. It would still be available via this.get('apollo'), and would proxy all calls to the actual apollo service, except that it would also track queries and route/component lifecycles. Then it could automatically unsubscribe from anything that was queried within the route/component when teardown is happening.

This might also enable some better designs for pagination (see #18). If the tracked observables are easily available to the developer (say with this.get('apolloQueries.myActiveQueryName')), then it would be trivial to call fetchMore() on the observable when you want to get another page of results.

One of the key design goals I'd like to achieve with this project is to avoid layering too much on top of Apollo Client. I hope that means it's easier to keep up with the project and we can avoid situations where functionality is available in the upstream but not easy to use in this addon.

Thoughts on whether this is a good idea or on how to implement it? Are there other projects out there with a similar model, where a service is wrapped to make it route-aware or component-aware?

Cannot use newer version of apollo-client

I attempted to upgrade the addon's core dependencies here: https://github.com/bgentry/ember-apollo-client/compare/upgrade-apollo-client

Unfortunately, that breaks the tests, resulting in the following console errors:

apollo-client.amd.js:47Uncaught SyntaxError: Unexpected token import
index.js:1Uncaught ReferenceError: define is not defined
    at index.js:1
app.js:1Uncaught ReferenceError: define is not defined
    at app.js:1
query-and-unsubscribe-test.js:1Uncaught ReferenceError: define is not defined
    at query-and-unsubscribe-test.js:1
tests?hidepassed:39 Uncaught ReferenceError: Ember is not defined
    at tests?hidepassed:39
test-loader.js:21Uncaught ReferenceError: require is not defined
    at HTMLDocument.<anonymous> (test-loader.js:21)

To upgrade, I ran:

yarn upgrade apollo-client graphql-tag graphql-tools graphql

I was able to narrow it down to the fact that it breaks as soon as apollo-client is upgraded beyond v0.6.0 (to v0.7.x or beyond).

My assumption is that this is due to the Apollo Client changes to use UMD and ES6 modules, which were released literally the day after this addon was first published.

I don't have time to dig into this any further right now, but if anybody feels inclined to take a crack at it, be my guest 😃

Auth support

There's no official mechanism for providing authorization headers or manipulating API requests before they go out. It should be pretty easy to do even without official support in this addon due to the way the client is exposed on the apollo service, and Apollo Client's built-in middleware support.

Even if no new code needs to be added to support this, it should be documented and tested explicitly.

Error: markSubscriptionsStale is not a function

I keep getting this error trying to use this package:

Error while processing route: authors this.get(...).markSubscriptionsStale is not a function

Found on line 9 of route-query-manager.js referencing this.get('apollo'):

Class {_super: ƒ, client: ApolloClient, __ember1522174837814: "ember184"}
client: ApolloClient
cache: InMemoryCache {optimistic: Array(0), watches: Array(0), silenceBroadcast: false, config: {…}, addTypename: true, …}
defaultOptions: {}
disableNetworkFetches: false
link: ApolloLink {request: ƒ}
mutate: ƒ ()
query: ƒ ()
queryDeduplication: true
reFetchObservableQueries: ƒ ()
resetStore: ƒ ()
resetStoreCallbacks: []
ssrMode: false
store: DataStore {cache: InMemoryCache}
version: "2.2.8"
watchQuery: ƒ ()

Design Pattern / Component Question

Scenario: A few routes in my app will contain recent activity / notifications components. Additionally, these can be displayed in a popover list from a toolbar on any route. For example, on the main dashboard, I will have an activity feed summary which shares state with the toolbar popout, but likely not the same component as the toolbar version might have limited features.

The conflicting opinions on Ember Data deal with when it's appropriate to inject the store into a component.

I'm currently passing the data retrieved from my graphql query in the route to both components. I'm not a fan of this method due to one of the components being deeply nested. I would rather just do a query / mutation from the component itself. Is this a bad idea / design pattern under certain circumstances (referring to the arguments about doing this with Ember Data). ie, will this cause data sync issues or anything similar?

Judging by "In a component, this cleanup is typically done with a willDestroyElement hook." from the docs, I assume this isn't an issue.

Thanks in advance.

Question: How to use computed properties if Models don't exist?

Hi Guys, Sorry for asking here, I looked for a slack room and didn't find one.

I see that this is a full Ember Data replacement. My question is that if that is the case, models in the model folder are no longer used. How do you then have computed properties that used to be on model?

For example, I used to have a Person model. And when data came down from the server it was of type Person. And therefore a fullName computed property could exist.

If no models exist in this apollo-client, how can I then ensure that data that comes back from GraphQL is of the right type to have all of it's needed CPs?

Thanks!

Error: Unexpected Token

When I create a graphql file, there's a rendering in my app js file like this:

const doc = {
  "kind": "Document",
  "definitions": [
    {
      "kind": "OperationDefinition",
      "operation": "query",
      "name": {
        "kind": "Name",
        "value": "author"
      },
      "variableDefinitions": [
        {
          "kind": "VariableDefinition",
          "variable": {
            "kind": "Variable",
            "name": {
              "kind": "Name",
              "value": "id"
            }
          },
          "type": {
            "kind": "NonNullType",
            "type": {
              "kind": "NamedType",
              "name": {
                "kind": "Name",
                "value": "String"
              }
            }
          },
          "defaultValue": null
        }
      ],
      "directives": [],
      "selectionSet": {
        "kind": "SelectionSet",
        "selections": [
          {
            "kind": "Field",
            "alias": null,
            "name": {
              "kind": "Name",
              "value": "author"
            },
            "arguments": [
              {
                "kind": "Argument",
                "name": {
                  "kind": "Name",
                  "value": "id"
                },
                "value": {
                  "kind": "Variable",
                  "name": {
                    "kind": "Name",
                    "value": "id"
                  }
                }
              }
            ],
            "directives": [],
            "selectionSet": {
              "kind": "SelectionSet",
              "selections": [
                {
                  "kind": "Field",
                  "alias": null,
                  "name": {
                    "kind": "Name",
                    "value": "firstName"
                  },
                  "arguments": [],
                  "directives": [],
                  "selectionSet": null
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "loc": {
    "start": 0,
    "end": 69
  }
};
export default doc;

The browser blows up on each export default doc rendered for every graphql file. This rendering seems unusual.

Following your examples, I have my graphql queries as such:

query author($id: String!) {
  author(id: $id) {
    firstName
    lastName
  }
}

Removing the graphql files removes the issue of course. As your docs state, best practice is to put your queries in gql/queries/ rather than the pod structure.

I've tried with the following scenarios:

Scenario 1

ember-cli: 3.0.0
node: v9.8.0
npm: v5.8.0

Scenario 2

ember-cli: 2.8.0
node: v8.9.4
npm: v5.6.0

Scenario 3

ember-cli: 2.8.0
node: v6.6.0
npm: v3.10.3

Improve tests

We have almost 80% coverage, which is very good. But the place we least test is where you most need, in apollo service, the heart of the addon. We need help with this.

image

Apollo Imperative Store Usable

I'm going to assume the answer is no, but has the imperative store API been setup in this client?

This makes it so you can update the local Apollo store after mutations. This would work perfectly hand-in-hand since watchQuery is being used by default by this Apollo client implementation.

Destructuring of `Ember.testing` will not work.

Ember.testing is a getter/setter in Ember, and destructuring like this will only read its value at the time the module is evaluated. In this case, Ember.testing will most likely be false when the module is evaluated, then change to true during the test. This behavior somewhat recently changed in emberjs/ember-test-helpers#227 (which is included in [email protected] / [email protected]).

I believe the fix here would be to remove the destructuring, and use Ember.testing directly inline.

https://github.com/bgentry/ember-apollo-client/blob/08842367133b6373b44f07575806009ce4d13c43/addon/services/apollo.js#L20-L22

https://github.com/bgentry/ember-apollo-client/blob/08842367133b6373b44f07575806009ce4d13c43/addon/services/apollo.js#L90-L92

Configurable networkInterface

It would be really useful to make the networkInterface configurable. So a user could easily extend the ApolloService and specify a different type of transport (e,g, batching).

Fastboot support

After the latest release I hopped, that this addon now has a fastboot support, but i get the following error: Error: Network error: XMLHttpRequest is not defined

I tried to set up a new ember app(2.16.0) with just ember-cli-fastboot(1.1.0) and ember-apollo-client(0.5.2) installed, but i still get the same error.

redux error about minified code / NODE_ENV === 'production'

After shipping a new version of my app using ember-apollo-client to production, I'm facing this message on browser's console:

You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) to ensure you have the correct code for your production build.

Example app from How to GraphQL is outdated

Hey @DevanB, just realized that the example app linked near the top of the readme is no longer up-to-date on best practices for this addon. Specifically, it’s using a really old version of the addon and hasn’t yet been upgraded to Apollo Client v2.

Do you or anybody else have the bandwidth to update the app & tutorial? Otherwise I may need to remove the link so it doesn’t lead new users astray.

imports require `npm:` prefix

As of now, this package's imports require the npm: prefix using browserify.

I tried moving beyond that with a series of shims (1 2 3). You can see some things I tried to do to make it work on the direct-imports branch.

However, that's broken. Apparently what I did results in multiple copies of graphql getting loaded by apollo-client, graphql-tools, and my app. The strict type checking in graphql means that the "same type" from different copies of graphql is not actually the same type.

That branch contains an acceptance test that goes to debugger when this error occurs (100% of the time on that branch).

I have no idea what I'm doing on this build pipeline stuff, and no clue about how to fix it. If you know how to help, please do!

`cache-and-network` fetchPolicy breaks with empty cache

When using the cache-and-network fetchPolicy option on a watchQuery, Apollo Client initially calls the Observer's next() function with undefined data:

{data: undefined, loading: true, networkStatus: 1, stale: true}

This causes an error in the Apollo service when attempting to call Ember.get() to fetch a particular resultKey from the result object: https://github.com/bgentry/ember-apollo-client/blob/e3e75dd8e38b45c84669c23822dbf45fbda43d6a/addon/services/apollo.js#L34

I believe the right thing to do here is just to check if both loading === true && data === undefined, and if so, just bail out of newDataFunc. Errors should still bubble up, and any cached data loads would still work. This would just handle the case where no data has been returned yet.

Fix should be easy but this will need a test. In my app, I encounter this on every initial query that uses cache-and-network.

How should we do pagination?

Hi, Blake.

We have already talked about it a couple of times on Slack. I'm bringing here the topic. Are you doing pagination? How are you doing it?

I've been playing with pagination for a while. My implementation was based on Relay-style cursor pagination and written on ember-apollo-client v0.1.2. I've faced some problems with observable queries and their subscription, so I had to use this.get('apollo.client').watchQuery to handle observable queries and their subscriptions by hand. I've updated ember-apollo-client to v0.2.2 and now my implementation is broken due to some changes on Apollo Core - but I know what I need to change.

I see, now, that it's time to stop putting my hands on Apollo Core and use more ApolloService. Because the things we need to handle on Ember are not straightforward. In exemple, since Apollo Core v0.8.0, query results are deep frozen, so we need to deep copy the query result to "defrost" it because Ember asks for an extensible object as a model. And ApolloService already handle this on query and queryOnce.

I have an exemple of my old implementation. It's a little bit outdated since it's not a production code, but it shows how I play with observable queries and their subscriptions.

I would love to see how do implement pagination. Are you relying on Apollo Core too? Do you think ember-apollo-client should mirror Apollo Core functions?

Documentation for core Apollo Client functions?

Now that the apollo client no longer has documentation for VanillaJS, how will we do it?

The React Apollo documentation has now become official. But it is also not feasible to do an entire documentation of that in Ember.js. We need a better strategy.

Import multiple mutation as alias

@bgentry

import { default as submitAnswers } from '../../gql/mutations/submitAnswers';
import { default as submit } from '../../gql/mutations/submit';

this.get('apollo').mutate({ submitAnswers, variables }, 'submitAnswers') throws an error -> TypeError: Cannot read property 'kind' of undefined at checkDocument

What is the proper way of using 2 mutations in the same controller?

Cannot set property '_apolloObservable' of null

I am having an issue with ember-apollo-client giving me this error when there are no documents found using the query.

With this particular Endpoint, When there is no matching Document, I get this response in graphiql and the Cannot set property '_apolloObservable' of null Error in the console.

{
  "data": {
    "Stat": null
  }
}

When there is a matching Document, I get this response in graphiql and no error in ember:

{
  "data": {
    "Stat": {
      "id": "cj8tubzz517jl0150uro8lvze",
      "level": 0
    }
  }
}

I would guess that it explodes because the ember-apollo-client wants to have an empty array on non documents but I am not sure.

Router

export default Ember.Route.extend(RouteQueryManager, {
    model(params) {
        const steamId = parseInt(params.steam_id)
        let variables = { steamId }
        return this.get('apollo').watchQuery({ query, variables }, "Stat");
    }
});

gql query

query StatsById($steamId: Int!) {
  Stat(steamId: $steamId) {
    id
    level
  }
}

Thanks :)

Addendum:
This renders to a simple template with {{model.level}}

Addendum2:
When I use query instead of watchQuery it works flawlessly.

JSON Response getting truncated

We have a query in our GraphQL server that can potentially return a very large JSON array ( we are trying to get CRUD permissions for UI elements).
Based on our tests, the response size is around 200K.
When we run this query in GraphiQL, the query works fine.
But the response gets truncated when we try to query through our Ember app using Apollo client
We find that this JSON gets truncated, at approx around 130K. Response parsing fails due to this.

Our Query

return get(this, 'apollo')
  .watchQuery({
    query: myImportedQuery,
    variables: {
      // my query specific variables
    },
    fetchPolicy: 'network-only'
  })
  .then((response) => {
    return response
  })

This is the error we get:

{
  "errors": [
    {
      "message": "Unexpected end of JSON input",
      "locations": [
        "SyntaxError: Unexpected end of JSON input\n    at JSON.parse (<anonymous>)\n    at http://localhost:4200/assets/vendor.js:75140:25\n    at tryCatcher (http://localhost:4200/assets/vendor.js:55417:21)\n    at invokeCallback (http://localhost:4200/assets/vendor.js:55595:33)\n    at publish (http://localhost:4200/assets/vendor.js:55581:9)\n    at http://localhost:4200/assets/vendor.js:46660:16\n    at invoke (http://localhost:4200/assets/vendor.js:14164:24)\n    at Queue.flush (http://localhost:4200/assets/vendor.js:14084:25)\n    at DeferredActionQueues.flush (http://localhost:4200/assets/vendor.js:14237:31)\n    at Backburner.end (http://localhost:4200/assets/vendor.js:14369:42)"
      ]
    }
  ]
}

Our chrome dev console:
screen shot 2018-04-10 at 4 07 51 pm

What could be causing this issue?
Is there any header we are missing?
Any setting in Apollo client which may affect the size of response it can parse?

We use https://github.com/graphql-java in the backend.
Since GraphiQL is able to get the entire response, we doubt if its a server issue.

Wrong fetch URL

My environment.js

let ENV = {
    apollo: {
      apiUrl: 'http://localhost:3000/graph',
    },
    modulePrefix: 'storified',
    environment,
    rootURL: '/',
    locationType: 'auto',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false
      }
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    }
  };

Model

export default Route.extend({
  apollo: service(),
  model(params) {
    const apollo = this.get('apollo');
    return apollo.query({ query: allUsers }, 'users');
  }
});

Query

query users {
  users{
    name,
    projects {
      id,
      name
    }
  }
}

storified

Am I missing something?

Issue (not updating while adding a new record)

Hi,
Lets have this scenario where:

  1. I loop and display throw a list of users from returned model using watchQuery.
  2. I update one existing users from the list via a mutation successfully, and all changes reflects on the already displayed list without any issues.
  3. I do the same by instead this time I add a new user successfully through a mutation but then on the list it doesn't show the new record I've added. Even if I get out of the route and came back.

Why is this happening, is there a solution?
Best,
Ivan

expose latest subscription metadata somehow?

When you subscribe to an Apollo Client ObservableQuery (returned by watchQuery), you provide it an object that includes a next function. That function is called with an ApolloQueryResult, which looks like this:

{data: undefined, loading: true, networkStatus: 1, stale: true}

I suspect that those final 3 properties would be useful for some cases, or at least the middle 2. The react-apollo project makes loading and networkStatus available on props.data.

I'm not sure what's the best way to expose them, though. It's easy to envision adding some more private properties on the result object once the promise has been resolved with data, which would cover the cache-and-network use case where cached data is returned first but still loading at the same time.

What about exposing the network and loading status for queries which haven't yet returned data? In the case of a route loading model data, that route wouldn't fully render anyway until the watchQuery promise resolved with data.

Is this info useful? For which use cases? If so, how should it be exposed?

RouteQueryManager doesn't play nice with loading substate

I have a route in my app called widgets.show that takes an ID param. I tried adding a loading substate to my app with a template named show-loading.hbs. Once I add this template and I transition between showing different widgets (updating the :id route param from i.e. 1 to 2), the following sequence of events happens:

  1. beforeModel() is called on the widgets.show route for the new ID 2. This causes the RouteQueryManager to mark all preexisting watch query subscriptions as stale, which is good. In this case, it's only the query for widget with ID 1 that is active and thus marked stale.
  2. model() gets called with the new ID 2, initiating the Apollo Client request and starting a subscription which is not stale.
  3. resetController() is called on the widgets.show route with isExiting=true. The RouteQueryManager then unsubscribes to all queries, which includes the pending query for the new widget. The transition argument to resetController() is null.
  4. The new widget route never leaves the loading state because its promise is never resolved (due to the subscription being unsubscribed).

The problem here is that RouteQueryManager uses isExiting to determine whether it should unsubscribe to all queries, or just those that were previously marked as stale. With a loading route, the previous widgets.show route is exited in favor of widgets.show_loading. If I remove the loading template, isExiting remains false and only the stale queries are removed.

I'm not sure right now how to solve this. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.