-
Notifications
You must be signed in to change notification settings - Fork 446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New deref doesn't work when deref'ing to a reference. #559
Comments
As of right now, with the new deref, no value-type can be bound to. so if the output is like {
foo: {
key: 'foo',
parent: null
bar: { $type: ref, value: ['to', 'ref'] }
}
} then you can only deref to |
The right option to address this issue is to special case to allow Imagine the following scenario: preload a series of references, and allow On Sep 28, 2015, at 8:53 AM, Michael Paulson notifications@github.com As of right now, with the new deref, no value-type can be bound to. so if the output is like { then you can only deref to foo — You received this message because you are subscribed to the Google Groups |
To get this straight the feature to develop is the following. if (derefValue.$type === $ref) {
var ref = followReference(derefValue.value);
return this._clone({_path: ref.path});
}
... do regular deref stuff here ... followReference will resolve any references that follow references themselves. |
Yes. That's about the size of it. JH On Sep 30, 2015, at 9:24 AM, Michael Paulson notifications@github.com To get this straight the feature to develop is the following. if (derefValue.$type === $ref) { followReference will resolve any references that follow references — You received this message because you are subscribed to the Google Groups |
@michaelbpaulson @falcor-build no that's not right. the value being passed in isn't the |
This could be a problem as it creates the old api, of which we were trying to avoid. Since I can just pass in any ole array, not whats actually in the secondary cache. But I don't know a good way around this issue. |
Why should we accept an Array? I want people to only bind to values JH On Sep 30, 2015, at 3:49 PM, Michael Paulson notifications@github.com This could be a problem as it creates the old api, of which we were trying — You received this message because you are subscribed to the Google Groups |
The problem is values that are retrieved in non |
After much discussion we will not support deref'ing an array. The major reason is the new deref is suppose to allow the secondary cache generated by the model to be derefable. This guarantees that the things being bound exist and by id, but allowing arrays gets us back to soft deref which is unstable/dangerous. So I'll be closing this issue based on above. |
@michaelbpaulson tell @jhusain to stop protecting me from myself ;) Seriously though, this is a breaking change. We used to be able to I'm sure there's some sort of metadata (private non-enumerable |
That is an interesting idea. It's worth considering, but it's very hard to I'm curious what your use case is? When do you retrieve a reference and no JH On Oct 4, 2015, at 8:58 PM, Paul Taylor notifications@github.com wrote: @michaelbpaulson https://github.com/michaelbpaulson tell @jhusain Seriously though, this is a breaking change. We used to be able to deref to I'm sure there's some sort of metadata (private non-enumerable __ref key, — You received this message because you are subscribed to the Google Groups |
@falcor-build @jhusain @michaelbpaulson I ran into this when I wrote a call function that computes references for an entity, but also fills in the data for those references. For example, { "jsonGraph": {
"user": {
"name": $atom("Paul"),
"favorite-titles": {
0: $ref(`titlesById[123]`),
1: $ref(`titlesById[789]`),
"length": $atom(2)
},
"recently-watched": {
0: $ref(`titlesById[456]`),
1: $ref(`titlesById[789]`),
"length": $atom(2)
}
},
"titlesById": {
123: { "name": $atom("Pulp Fiction") },
456: { "name": $atom("Danger 5") },
789: { "name": $atom("Unsealed Alien Files") }
}
} } The JSON result from the { "json": {
"user": {
"name": "Paul",
"favorite-titles": {
0: ["titlesById", 123],
1: ["titlesById", 789],
"length": 2
},
"recently-watched": {
0: ["titlesById", 456],
1: ["titlesById", 789],
"length": 2
}
},
"titlesById": {
123: { "name": "Pulp Fiction" },
456: { "name": "Danger 5" },
789: { "name": "Unsealed Alien Files" }
}
} } From here I'd like to use the respective lengths of |
@trxcllnt it turns out, given your example, I think I have figured out what is happening here. This is actually an issue with the Router. Your https://github.com/Netflix/falcor-router/blob/master/src/run/call/runCallAction.js#L108 I'll file an issue with falcor-router. |
@michaelbpaulson unfortunately, I can't retrieve the data beyond the references using suffixes because in my case, the Also, I should clarify: I'm using special branches in my forks of both falcor and falcor-router, which have some outstanding PR's/fixes already merged. |
@trxcllnt Now I think I get it, here is the jsonGraph that is reported from you call { "jsonGraph": {
"user": {
"name": $atom("Paul"),
"favorite-titles": {
0: $ref(`titlesById[123]`),
1: $ref(`titlesById[789]`),
"length": $atom(2)
},
"recently-watched": {
0: $ref(`titlesById[456]`),
1: $ref(`titlesById[789]`),
"length": $atom(2)
}
},
"titlesById": {
123: { "name": $atom("Pulp Fiction") },
456: { "name": $atom("Danger 5") },
789: { "name": $atom("Unsealed Alien Files") }
}
},
"paths": [
['user', 'name'],
['user', 'favorite-titles', 'length'],
['user', 'favorite-titles', [0,1]],
['user', 'recently-watched', 'length'],
['user', 'recently-watched', [0,1]],
['titlesById', [123, 456, 789], 'name']
] } If I have guessed your paths correctly then I see the problem. Your call function is reporting the paths incorrectly. The paths should be reported as the following. "paths": [
['user', 'name'],
['user', 'favorite-titles', 'length'],
['user', 'favorite-titles', [0,1], 'name'], // you know in your call function what extra leaves you need
['user', 'recently-watched', 'length'],
['user', 'recently-watched', [0,1], 'name'] // same as above comment.
] } |
tl;dr: I could make it work without needing a I looked back at the code that caused this, so I have a better example now: import falcor from 'falcor';
import Router from 'falcor-router';
const $ref = falcor.ref;
const $atom = falcor.atom;
const $pv = falcor.pathValue;
const router = new Router([{
/* search by customer name */
route: ['search', 'titles-by-name'],
call(callPath, [searchTerm]) {
return fuzzySearchByTitleName(searchTerm)
.flatMap(titles => titles.map(({ id, name, rating, relatedTitles }, titleIndex) => {
const titleByIdPath = ['titles-by-id', id];
const pathValues = [
$pathValue(['search', 'titles-by-name', searchTerm, titleIndex], $ref(titleByIdPath))
];
pathValues.push(
$pathValue(titleByIdPath.concat('id'), $atom(id)),
$pathValue(titleByIdPath.concat('name'), $atom(name)),
$pathValue(titleByIdPath.concat('rating'), $atom(rating))
);
let relatedIndex = 0;
const relatedLen = relatedTitles.length;
if (relatedLen > 0) {
const relatedPath = titleByIdPath.concat('related-titles');
do {
const relatedTitle = relatedTitles[relatedIndex];
const relatedTitleId = relatedTitle.id;
pathValues.push($pathValue(
titleByIdPath.concat(relatedIndex),
$ref(['titles-by-id', relatedTitleId])
));
} while (++relatedIndex < relatedLen);
}
return pathValues;
})
.concat($pathValue('search', 'titles-by-name', searchTerm, 'length', $atom(titles.length)))
);
}
}]);
const model = new falcor.Model({ dataSource: router });
function searchTitles(searchTerm) {
model.call(['search', 'titles-by-name'], [searchTerm]).subscribe(({json}) => {
const titleModels = [];
const titlesByName = json.search['titles-by-name'];
const titlesLen = titlesByName.length;
let titlesIndex = -1;
while (++titlesIndex < titlesLen) {
const title = titlesByName[titlesIndex]; // title is an Array
titleModels.push(model.deref(title)); // deref doesn't like Arrays :(
}
});
} I could change this to append all the title information to the path prefix |
@trxcllnt So the fix for you is that path values can follow references, which make sense for call preload cases. This could be easily accomplished. Netflix/falcor-router#142 |
model.deref(json.someKeyThatIsAReference)
doesn't work because we don't attach the private__path
or__key
properties to ref values. We could do that, but then we'd need to clone the ref Array value every time. Another approach allowingderef
to still accept a Path as an argument.The text was updated successfully, but these errors were encountered: