I have the following:
// In the service
me: Ember.computed('token', function() {
return this.container.lookup('service:store').findRecord('user', 63);
}
// In the template - Works
{{this.currentSession.me.profile.firstName}}
Above works as expected. However, if I replace findRecord with query and throw it a filter param:
// In the service
me: Ember.computed('token', function() {
return this.container.lookup('service:store').query('user', { filter: { token: this.get('token') } });
}
// In the template - Works
{{this.currentSession.me.lastObject.profile.firstName}}
The lastObject is required, since the result from query is a collection. I am wondering if it is possible to get this work without doing lastObject. i.e.
{{this.currentSession.me.profile.firstName}}
I tried to put the lastObject in the computed property, like:
return this.container.lookup('service:store').query('user', { filter: { token: this.get('token') } }).lastObject;
To no avail. Any thoughts?
Try this:
return this.container.lookup('service:store').query('user', { filter: { token: this.get('token') } }).then(function(users){
return users.get('lastObject');
});
Related
I'm performing a query to get PowerMeter details in which contains another type inside called Project. I write the query this way:
query getPowerMeter($powerMeterId: ID!) {
powerMeter: powerMeter(powerMeterId: $powerMeterId) {
id
name
registry
project {
id
name
}
}
}
When I perform the query for the first time, project is successfully returned. The problem is that when I perform subsequent queries with the same parameters and default fetchPolicy (cache-first), project isn't returned anymore.
How may I solve this problem?
Also, I call readFragment to check how powerMeter is saved in the cache and the response shows that powerMeter has project saved.
const frag = client.readFragment({
fragment: gql`
fragment P on PowerMeter {
id
name
registry
project {
id
name
}
}
`,
id: 'PowerMeter:' + powerMeterId,
});
Power Meter returned first time
{
"powerMeter":{
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":{
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
},
"__typename":"PowerMeter"
}
}
Fragment after calling power meter first time
{
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":{
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
},
"__typename":"PowerMeter"
}
Power Meter returned second time
{
"powerMeter":{
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"__typename":"PowerMeter"
}
}
Fragment after calling power meter second time
{
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":{
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
},
"__typename":"PowerMeter"
}
Edit 1: Fetching Query
The code below is how I'm fetching data. I'm using useApolloClient and not a query hook because I'm using AWS AppSync and it doesn't support query hook yet.
import { useApolloClient } from '#apollo/react-hooks';
import gql from 'graphql-tag';
import { useEffect, useState } from 'react';
export const getPowerMeterQuery = gql`
query getPowerMeter($powerMeterId: ID!) {
powerMeter: powerMeter(powerMeterId: $powerMeterId) {
id
name
registry
project {
id
name
}
}
}
`;
export const useGetPowerMeter = (powerMeterId?: string) => {
const client = useApolloClient();
const [state, setState] = useState<{
loading: boolean;
powerMeter?: PowerMeter;
error?: string;
}>({
loading: true,
});
useEffect(() => {
if (!powerMeterId) {
return setState({ loading: false });
}
client
.query<GetPowerMeterQueryResponse, GetPowerMeterQueryVariables>({
query: getPowerMeterQuery,
variables: {
powerMeterId,
},
})
.then(({ data, errors }) => {
if (errors) {
setState({ loading: false, error: errors[0].message });
}
console.log(JSON.stringify(data));
const frag = client.readFragment({
fragment: gql`
fragment P on PowerMeter {
id
name
registry
project {
id
name
}
}
`,
id: 'PowerMeter:' + powerMeterId,
});
console.log(JSON.stringify(frag));
setState({
loading: false,
powerMeter: data.powerMeter,
});
})
.catch(err => setState({ loading: false, error: err.message }));
}, [powerMeterId]);
return state;
};
Edit 2: Fetching Policy Details
When I use fetchPolice equals cache-first or network-only, the error persists. When I use no-cache, I don't get the error.
I think this might have been the solution:
https://github.com/apollographql/apollo-client/issues/7050
Probably way too late, but it could help people coming to this issue in the future.
When using apollo client's InMemoryCache it seems you need to provide a list of possible types so the fragment matching can be done correctly when using the InMemoryCache.
You can do that manually when having few union types and a pretty stable API which doesn't change very often.
Or you automatically generate these types into a json file, which you can use directly in the InMemoryCache's possibleTypes config directly.
Visit this link to the official docs to find out how to do it.
Cheers.
This is how I get all data in config.js:
this.get('/rentals', function (schema, request) {
if (request.queryParams.value) {
// The code should be here...
} else {
return schema.rentals.all();
}
}
I looked at documentation, but there's no way to get filtered ones. Apparently there are commands like all(), find(), findBy(), create(), etc. But there's nothing that filters out and returns. Any help?
Figured out: filter could be used with all().
this.get('/rentals', function (schema, request) {
if (request.queryParams.value) {
let filteredRentals = schema.rentals.all().filter(function (i) {
return i.attrs.value.toLowerCase().indexOf(request.queryParams.value.toLowerCase()) !== -1;
});
return filteredRentals;
}
return schema.rentals.all();
});
I'm trying to search for all employees that have a title of developer
As per the documentation (http://guides.emberjs.com/v1.10.0/models/finding-records/) It seems the correct way to do this is:
return this.store.find('employee', { title: "developer" });
But this is not working in Ember CLI 0.2.2, and I can't even see my template when I try this, even though when I do
return this.store.find('employee')
I can see a list of all employees and there are multiple employees with that title
Turns out I needed to override the DS.FixtureAdapter::queryFixtures method. I went into my adapters/application.js file and added
queryFixtures: function(records, query, type) {
return records.filter(function(record) {
for(var key in query) {
if (!query.hasOwnProperty(key)) { continue; }
var value = query[key];
if (record[key] !== value) { return false; }
}
return true;
});
}
how to return some value from actions??
I tried this:
var t = this.send("someAction", params);
...
actions:{
someAction: function(){
return "someValue";
}
}
actions don't return values, only true/false/undefined to allow bubbling. define a function.
Ember code:
send: function(actionName) {
var args = [].slice.call(arguments, 1), target;
if (this._actions && this._actions[actionName]) {
if (this._actions[actionName].apply(this, args) === true) {
// handler returned true, so this action will bubble
} else {
return;
}
} else if (this.deprecatedSend && this.deprecatedSendHandles && this.deprecatedSendHandles(actionName)) {
if (this.deprecatedSend.apply(this, [].slice.call(arguments)) === true) {
// handler return true, so this action will bubble
} else {
return;
}
}
if (target = get(this, 'target')) {
Ember.assert("The `target` for " + this + " (" + target + ") does not have a `send` method", typeof target.send === 'function');
target.send.apply(target, arguments);
}
}
I had the same question. My first solution was to have the action put the return value in a certain property, and then get the property value from the calling function.
Now, when I need a return value from an action, I define the function that should be able to return a value seperately, and use it in an action if needed.
App.Controller = Ember.Controller.extend({
functionToReturnValue: function(param1, param2) {
// do some calculation
return value;
},
});
If you need the value from the same controller:
var value = this.get("functionToReturnValue").call(this, param1, param2);
From another controller:
var controller = this.get("controller"); // from view, [needs] or whatever
var value = controller.get("functionToReturnValue").call(controller, param1, param2); // from other controller
The first argument of the call() method needs to be the same object that you are running the return function of; it sets the context for the this reference. Otherwise the function will be retrieved from the object and ran from the current this context. By defining value-returning functions like so, you can make models do nice stuff.
Update I just found this function in the API that seems to do exactly this: http://emberjs.com/api/#method_tryInvoke
Look this example:
let t = this.actions.someAction.call(this, params);
Try
var t = this.send("someAction", params);
instead of
vat r = this.send("someAction", params);
Just use #set for set value which you want to return
actions:{
someAction: function(){
// return "someValue";
this.set('var', someValue);
}
}
Hey everyone,
i do the following query to get a user statuses:
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM statuses WHERE uid = ' + userId
},
function(data) {
// do something with the response
}
);
It works great when the number of result are more than 0.
but when there are no results, the callback function is not called at all.
i need to know if there are 0 rows returning from this query, is there any way to do it?
Thanks :)
First of all, the statuses table does not exists. You should be using status table.
The callback is always called but you should properly check against empty objects. Just paste this on the Javascript Test Console:
<fb:login-button scope="read_stream">
Grant access to statuses
</fb:login-button>
<button onclick="getStatuses()">Get Statuses</button>
<script>
window.getStatuses = function() {
FB.api(
{
method: 'fql.query',
query: 'SELECT message FROM status WHERE uid = me() AND time < 315532800'
},
function(data) {
if(!isEmpty(data)) {
for(var key in data) {
var obj = data[key];
console.log(obj['message'])
}
} else {
console.log("data is empty")
}
});
};
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
</script>
Here I am checking for statuses before 1/1/1980 to insure that an empty result is returned. In your console you should note the data is empty response.
When there are no results from a query, you should be getting an empty array.
Also, there isn't a FQL table named "statuses", it's "status".