Is anyone aware of a next/previous component that works inside WebVR with Aframe, so that if I am looking at an entity with id entity1 at position 0 0 -3, then I click next and I am looking at an entity with id entity2 at position 0 0 -3 replacing the previous entity, the previous entity returns position y -3 and scale 0 0 0, I click next again and now I am looking at entity with id entity3 which is now at position 0 0 3
I have been exploring how to build a next button starting with either an array or a javascript switch so that each time I press click, (listening for clicks on the next button) it brings me another new entity, so I might click next 6 times and see 6 different entities at position 0 0 -3, with each new entity replacing the previous entity, similarly a back button would do the same process but in reverse order.
Here is the idea in code, I am trying to complete it, but I’m getting lost in the forest for the trees so to speak.
AFRAME.registerComponent("carousel", {
init: function() {
this.el.addEventListener("turn_carousel_left", (e) => {
document.querySelectorAll('.carousel_left').forEach(function(e){
e.emit('close_the_menu');
emit +1 carousel index
this.el.addEventListener("turn_carousel_right", (e) => {
listen right events
emit -1 carousel index
if carousel index = 1 then emit position_named_1
selected_carsouel_item = carousel_index_list[carouselindex]
http://carousel-b.glitch.me
Related
I need to build something like a lazy loaded list with Firebase, meaning I load an initial 10 items or something like that, whenever the user scrolls to the bottom of the list, I load 10 more items.
I have two problems:
How do I know when the user has scrolled to the bottom?
How do I update a query most effectively?
I currently query like this:
List myItems;
BehaviorSubject myItemsSubject = new BehaviorSubject();
int currentlyLoadedItems = 10;
// I call this in my constructor:
loadItems() {
Firestore.instance.collection('MyCollection').orderBy('position', descending: true).limit(currentlyLoadedItems).snapshots().listen((QuerySnapshot snaps) {
myItems = snaps.documents.map((DocumentSnapshot doc) {
return Workout.formDoc(doc);
}).toList();
myItems.add(myItems);
});
}
the when user scrolls to bottom I do this:
loadMoreItems() {
currentlyLoadedItems += 10;
loadItems();
}
The problem with this solution is, I always need to load the already loaded items again. Because when I have loaded the first 10 items and I call loadMoreItems() I load the first 20 items, so I have loaded the first 10 items twice.
Is there a better way to update a query?
In this component code I am trying to use an event to select the meaning of the variable called "name"
to select which entity will copy another entities rotation as the user watches.
Different events will result in different rotations.
So event 1 means that name equals querySelector Object A
Then I am trying to have row get it's own rotation and give it to name's (to) animation and then start
name's animation by emitting moveobject to name.
However I am currently stuck on this problem after investing many hours trying to solve it. Help?
AFRAME.registerComponent("comp", {
init: function () {
let name = {}
this.el.addEventListener("event1", (e) => {
name = document.querySelector('#objectA');
console.log('event1')
// line 13? comp.emit('rowstart)
});
this.el.addEventListener("event2", (e) => {
name = document.querySelector('#objectB');
console.log('event2')
});
let row = document.querySelector('#rowA');
row.addEventListener('rowstart', function (e) {
var rotation = row.getAttribute('rotation')
name.setAttribute('animation', {
to: {
x: rotation.x,
y: rotation.y,
z: rotation.z - 30
}
})
name.emit('moveobject')
});
}
});
I should mention that this link below is what my code looks like when it is ONLY copying rotation, and not using an event to select which entity will be rotated https://glitch.com/edit/#!/copy-rotation?path=index.html:37:8 (edited)
to is not a vector property, you have to pass it as a string.
name.setAttribute('animation', 'to', `${rotation.x} ${rotation.y} ${rotation.z}`);
See the example code:
https://codesandbox.io/s/G5A04RB23
State is simple, contains only a single value. Both Sub and App is connected to redux. When click the dispatch button, value incremented. And App will clear the state in componentWillReceiveProps when the value reaches 3.
But from the console log, it appears Sub never sees the 3 state.
VM220:80 action
VM220:21 reducer
VM220:83 dispatch: 0.525146484375ms
VM220:52 app prop 1
VM220:58 app render 1
VM220:32 sub prop 1
VM220:35 sub render 1
VM220:80 action
VM220:21 reducer
VM220:83 dispatch: 0.485107421875ms
VM220:52 app prop 2
VM220:58 app render 2
VM220:32 sub prop 2
VM220:35 sub render 2
VM220:80 action
VM220:21 reducer
VM220:83 dispatch: 0.4931640625ms
VM220:52 app prop 3 <<< app see 3
VM220:58 app render 3
VM220:32 sub prop 0 <<< sub never see 3
VM220:35 sub render 0
VM220:52 app prop 0
VM220:58 app render 0
I thought with redux, state should be consistent to all the components and every component should see the same state all the time. Is this the expected behavior or what am I doing wrong here?
EDIT1
Also tried with raw redux (instead of react-redux): https://codesandbox.io/s/Jq6gBoGzK
This time we do see both app and sub see the state value=3
So it appears to be a react-redux behavior. But it's a bit surprising behavior to me, I still expect all the components see every state change (thus props change). See my graph below:
Expect:
state1 -> (update props of comp1 ... compN) -> state2
Actual:
state1 -> (update props of comp1) -> state2 -> (update props of comp2)
Any reason why react-redux doing this instead of my expecting?
sub listener 1
app listener 1
sub listener 2
app listener 2
sub listener 3
app listener 3
sub listener 0
app listener 0
Here's what's happening behind the scenes when you're rendering your app:
Get props from Redux for the App component
Call App::componentWillReceiveProps() with props from step #1
Call App::render() with props from step #1
App::render() tells React to render the Sub component
Get props from Redux for the Sub component
Call Sub::componentWillReceiveProps() with props from step #5
Call Sub::render() with props from step #5
When you dispatch the clearAction() event in App::componetWillReceiveProps() (between steps #2 and #3), Redux immediately changes the value property in the store from 3 to 0, so by the time you get to step #5, the Redux store contains value=0, which is why it appears that the Sub component never sees the value=3.
You can see this by tweaking your code and calling store.dispatch(clearAction()); after a timeout:
if (nextProps.value == 3) {
setTimeout(function() {
store.dispatch(clearAction());
}, 1000); // dispatch the clearAction() after one second
}
With that change you should see the value=3 render all the way down to the Sub component, and then automatically change to value=0 one second after your click when the clearAction() event gets dispatched.
In basic, I have one component with integer data in list and second component with action (like +1 operation) I want to open app('/'), click by one of integer and redirect to other page(/int/13). On this page i want to see old list of integers data and my number + 1 (14).
My routes is this
{path: '', component: IntegerComponent,
{path: 'int/:id', component: ActionComponent}
After open (/) i see integer data from IntegerComponent
<li *ngFor="let int of ints [routerLink]="['/int', int]">
<p>{{int | json}}</p>
</li>
And after click i really see int number + 1, but i need to see this with integer data together, on one page. Without reloading data from server. Only adding new.
I find answer by myself!! Need to use children for routing and in int template add <router-outlet></router-outlet>. Then, if user is clicked by int - result of action will show in this outlet, and main outlet will keep
When using RefluxJS stores with asynchronous actions, you can easily end up having race conditions between your actions.
Abstract description of the issue
For example, our store is in state X. An async action A is called from X, and before it finishes, another async action B is called, also from X. From here, no matter which action finishes first, it goes wrong.
B finishes first with a state Y1, A finishes last and overwrites the state Y1 with Y2.
A finishes first with a state Y2, B overwrites Y2 with Y1.
The desired behavior would be to have:
A B
X -> Y -> Z
Where B is not based on X, but on Y, and leads to a consistent Z state, instead of two actions based on the same state, leading to an inconsistent state:
A
X -> Y1 .--> Y2
\ /
'----'
B
Implemented example of the issue
I wrote a minimal working example, running with Node, of the problem I am talking about.
var Q = require('q');
var Reflux = require('reflux');
var RefluxPromise = require('reflux-promise');
Reflux.use(RefluxPromise(Q.Promise));
var AsyncActions = Reflux.createActions({
'add': { asyncResult: true }
});
var AsyncStore = Reflux.createStore({
init: function () {
// The state
this.counter = 0;
AsyncActions.add.listenAndPromise(this.onAdd, this);
},
// Increment counter after a delay
onAdd: function(n, delay) {
var that = this;
return apiAdd(this.counter, n, delay)
.then(function (newCounter) {
that.counter = newCounter;
that.trigger(that.counter);
});
}
});
// Simulate an API call, that makes the add computation. The delay
// parameter is used for testing.
// #return {Promise<Number>}
function apiAdd(counter, n, delay) {
var result = Q.defer();
setTimeout(function () {
result.resolve(counter + n);
}, delay);
return result.promise;
}
// Log the store triggers
AsyncStore.listen(console.log.bind(undefined, 'Triggered'));
// Add 3 after 1 seconds.
AsyncActions.add(3, 1000);
// Add 100 almost immediately
AsyncActions.add(100, 1);
// Console output:
// > Triggered 100
// > Triggered 3
// Desired output (queued actions):
// > Triggered 3
// > Triggered 103
With these dependencies in package.json
{
"dependencies": {
"q": "^1.3.0",
"reflux": "^0.3",
"reflux-promise": "^1"
}
}
Nature of the question
I expected RefluxJS to queue actions, but it doesn't. So I am looking for a way to order these actions correctly. But even if I managed to queue up these actions in some way (so B is issued after A) how can I be certain that, when A finishes, issuing B is still a valid action ?
Maybe I am using RefluxJS the wrong way in the first place, and this scenario does not happen in a properly structured app.
Is queuing of the asynchronous actions (assuming this is possible within a Reflux app) the solution ? Or should we work on avoiding these scenarios in the first place, somehow ?
Your example seems like more of an issue with the concept of "source of truth" than anything else. You're storing the current state of the number ONLY client side, but ONLY updating it after receiving confirmation from the server side on an operation being done to it.
Of course that'll make issues. You're mixing the actions upon the number and the storage of the number in a weird way where there's no single source of truth for what the number is at any given moment. It's in limbo between the time when the action is called finished...and that's no good.
Either store the number client side, and every time you add to it, add to that number directly and then tell the server side what the new number is... (i.e. the client side is taking responsibility as the source of truth for the number while the client side runs)
OR store the number server side, and every time you up it with an action from the client side, the server returns the new updated number. (i.e. the source of truth for the number is completely server side).
Then, even if race issues occur, you still have a source of truth for what the number is, and that source can be checked and confirmed. For example, if the server side holds the source of truth for the number then the API can also return a timestamp for the status of that value every time it returns it, and you can check it against the last value you got from the API to make sure you're ACTUALLY using the newest value.