I am trying to set a observable to the mouse co-ordinate using RxJs. But i am getting error as 'Observable` is not defined.
any one help me here?
here is my code :
$(document).ready(function() {
var mouseMoves = Observable.fromEvent( mouseDown )
.takeUntil( mouseUp )
.map( function( mouseEvent) {
return {
x : mouseEvent.clientX,
y : mouseEvent.clientY
}
})
mouseMoves.subscribe( function ( cords ) {
console.log( cords );
// $('#results').html( cords );
})
});
Live Demo
You can use Rx.Observable instead of Observable:
var mouseMoves = Rx.Observable.fromEvent( mouseDown )
.takeUntil( mouseUp )
.map( function( mouseEvent) {
return {
x : mouseEvent.clientX,
y : mouseEvent.clientY
}
})
Related
I tried using CKEditor5 for my project and when I activated insert image and tried using it, It says ReferenceError: server is not defined. Here is the code:
class MyUploadAdapter {
constructor( loader ) {
this.loader = loader;
}
upload() {
server.onUploadProgress( data => {
loader.uploadTotal = data.total;
loader.uploaded = data.uploaded;
} );
return loader.file
.then( file => server.upload( file ) );
}
abort() {
// Reject the promise returned from the upload() method.
server.abortUpload();
}
_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();
xhr.open( 'POST', '{{ route('ck5_store')}}',true );
xhr.setRequestHeader('X-CSRF-TOKEN',$('meta[name="csrf-token"]').attr('content'));
xhr.responseType = 'json';
}
_initListeners( resolve, reject, file ) {
const xhr = this.xhr;
const loader = this.loader;
const genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener( 'error', () => reject( genericErrorText ) );
xhr.addEventListener( 'abort', () => reject() );
xhr.addEventListener( 'load', () => {
const response = xhr.response;
if ( !response || response.error ) {
return reject( response && response.error ? response.error.message : genericErrorText );
}
resolve( {
default: response.url
} );
} );
if ( xhr.upload ) {
xhr.upload.addEventListener( 'progress', evt => {
if ( evt.lengthComputable ) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
} );
}
}
_sendRequest( file ) {
const data = new FormData();
data.append( 'upload', file );
this.xhr.send( data );
}
}
function SimpleUploadAdapterPlugin( editor ) {
editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
return new MyUploadAdapter( loader );
};
}
ClassicEditor
.create( document.querySelector( '#tab-content-{{$MODULE}} form#{{$MODULE}}_form textarea[id=form_{{$MODULE}}_details]') ,
{
extraPlugins: [ SimpleUploadAdapterPlugin ],
})
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
Any idea on what is the problem? Already tried looking for solutions but cannot find anywhere else. Thank you in advance.
I was having the same issue. My solution:
// Starts the upload process.
upload() {
return this.loader.file
.then( file => new Promise( ( resolve, reject ) => {
this._initRequest();
this._initListeners( resolve, reject, file );
this._sendRequest( file );
} ) );
}
// Aborts the upload process.
abort() {
if ( this.xhr ) {
this.xhr.abort();
}
}
I found this solution following documentation.
I'm attempting to do conditional loading of a model into an a-entity. The reason for this is that I've got a scene which I would like to give the user a choice to load a large model or not. So far I've got a scene with the following entity:
id="modelname-entity"
scale="2 2 2"
position="0 0 -5"
drag-rotate="rotateY:false;"
model-rotate-loadprogress="modelUrl:modelname.gltf;modelRef:modelname-model"
></a-entity>
which has a component model-rotate-loadprogress which loads the gltf model with THREE.js syntax:
AFRAME.registerComponent('model-rotate-loadprogress',{
schema : {
modelUrl: {
type: "string"
},
modelRef: {
type: "string"
}
},
init : function(){
this.loadModel();
},
loadModel: function() {
if (!this.data.modelUrl || !this.data.modelRef) {
console.warn("Model details not given for model rotate loader");
return;
}
if ( document.getElementById(this.data.modelRef) ) {
console.warn("Assets already has an asset with the ID of " , this.data.modelRef );
}
// Using THREE.js file loader
var dis = this;
var loader = new THREE.GLTFLoader().setPath( '/assets/static/models/' );
loader.load(
this.data.modelUrl,
gltf => {
// Add the model to the scene for now.
dis.el.sceneEl.object3D.add(gltf.scene);
},
xhr => {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
error => {
console.error( error );
}
);
}
}
The model loads and gets displayed to the scene but how to I attach it to the entity instead?
I got the model populating the <a-entity> in the similar way to how I got it attaching it to the scene. Here's the final code:
loadGLTFModel: function() {
var dis = this;
var loader = new THREE.GLTFLoader().setPath( this.PATH_MODELS );
loader.load(
`${this.PATH_MODELS}${this.data.gltfModel}`,
gltf => {
dis.el.object3D.add(gltf.scene)
},
progress => {
this.onProgress(progress);
},
error => {
console.error( "ERROR : " , error );
}
);
},
onProgress: function(progress) {
this.progressBar.setAttribute("geometry", {
thetaLength: (progress.loaded / progress.total * 360)
})
},
If I were to add the heavy model to the <a-assets> which is the recommended way of doing things, would result in the whole application being blocked until all the assets are loaded and ready. In my scenario the user has a choice of skipping the download. If the user chooses to load the model then he/she gets a progressbar (actually a ring) which gets updated.
Here's code how to load obj and mtl models:
loadOBJModel: function() {
var dis = this;
if (!this.data.mtlMaterial) {
console.error("No material given for model");
return;
}
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load(
`${this.PATH_MODELS}${this.data.mtlMaterial}`,
materials => {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( this.PATH_MODELS );
objLoader.load(
this.data.objModel,
object => {
dis.el.object3D.add(object)
},
progress => {
this.onProgress(progress);
},
error => {
console.error( "ERROR : " , error );
}
);
}
);
},
No need to invoke the GLTFLoader. Use the gltf-model component:
loadModel: function() {
if (!this.data.modelUrl || !this.data.modelRef) {
console.warn("Model details not given for model rotate loader");
return;
}
if ( document.getElementById(this.data.modelRef) ) {
console.warn("Assets already has an asset with the ID of " , this.data.modelRef );
}
this.el.setAttribute(‘gltf-model’, ‘url(‘ + this.data.modelUrl + ‘)’);
}
I recommend pre loading the model in a-assets so user doesn’t have to wait for network. Pre load both the large and small models.
I'm new to RxJ.
The version of RxJS 6.2.
I'm trying fromEvent method and filtering out mouse event info but it shows mouse position data even when clientX is bigger than 500 and seems filter method is not working.
Could anyone tell me what I'm doing wrong and how to fix it?
JavaScript
import { Observable, fromEvent } from "rxjs";
import { map, filter } from 'rxjs/operators';
let numbers = [1, 5, 10];
const source = fromEvent(document, "mousemove");
source.pipe(
map((e: MouseEvent) => {
return {
x: e.clientX,
y: e.clientY
}
}),
filter(value => value.x < 500)
)
source.subscribe(
value => console.log(value),
e => console.log(`error: ${e}`),
() => console.log('complete')
);
The call to pipe returns a new observable - which you are ignoring. It does not modify the source observable.
You should subscribe to the observable returned by pipe instead of the source observable:
const source = fromEvent(document, "mousemove");
const mappedAndFiltered = source.pipe(
map((e: MouseEvent) => {
return {
x: e.clientX,
y: e.clientY
};
}),
filter(value => value.x < 500)
);
mappedAndFiltered.subscribe(
value => console.log(value),
e => console.log(`error: ${e}`),
() => console.log('complete')
);
While using the new Dojo Event (on) i'm getting a lot of loops.
I'm calling for the first time as doShowSomeDialog(null).
Why does this function get into a loop?
(dialog has been declared before as dijit/Dialog)
doShowSomeDialog = function ( value ) {
var selectName = 'selector';
if ( value ) {
dialog.set("href", "/url/"+ selectName +"/"+ value );
} else {
dialog.set("href", "/url");
dialog.show();
}
dialog.set("onDownloadEnd", function() {
on( dijit.byId(selectName ), "change", doShowSomeDialog( dijit.byId( selectName ).get('value') ) );
}); }
It seems that "on" executes on the declaration of the event.
This will execute the method when calling on. You should wrap it in it's own function.
doShowSomeDialog( dijit.byId( selectName ).get('value')
should become
function() { doShowSomeDialog( dijit.byId( selectName ).get('value'); }
I'm struggling with a MVC pattern around Stateful objects and Observable stores. I can't find clarity on when to use one over another and mixing them isn't as clean as I'd hoped. Any Ah! insight into how to manage an observable collection of stateful items?
If I do a item.set("key", value) I can item.watch("key", cb) but then my observe-er isn't notify-ed.
I can do a item.watch(function() { state.notify(item, item.id); }) to always notify my observer but if my observe-er calls set I get a "Query is out of date, you must observe() the query prior to any data modifications'" error I cannot reconcile.
I can decouple this via a setTimeout but it's not feeling good.
Here's some code to show what I'm trying:
crudify: function ( store, query, crud )
{
var result;
if ( !crud )
{
crud = query;
query = store;
store = null;
}
if ( store )
{
query = store.query( query );
}
result = query.observe( function ( row, deleteIndex, insertIndex )
{
var del = ( 0 <= deleteIndex ), ins = ( 0 <= insertIndex );
!del && ins && crud.c && crud.c( row );
del && ins && crud.u && crud.u( row );
del && !ins && crud.d && crud.d( row );
}, !!crud.u );
crud.c && array.forEach( query, crud.c );
return result;
}
And I have a store wrapper (for layers) which I'm hacking to pieces trying to get the observe-ers notified of data changes without getting errors:
addLayer: function ( item ) {
var that = this;
that.store.add(item);
item.watch && item.watch(function (name, prior, curr) {
if (prior !== curr) {
that._queue.push(item);
// attempting to eliminate queries which indirectly update the store (can't find source of error)
infor.delay(20, "LayerProcessorStoreNotification", function () {
that._queue.forEach(function (item) {
that.store.notify(item, that.getLayerId(item));
});
that._queue = [];
});
}
});
return item;
},
The delay method looks like this:
delay: function ( timeout, id, callback )
{
this.delays = this.delays || [];
var delay = this.delays[id];
if ( delay )
{
clearTimeout( delay );
}
delay = setTimeout( callback, timeout );
this.delays[id] = delay;
},
I can do a item.watch(function() { state.notify(item, item.id); }) to always notify my observer
I didn't have any problems using this pattern, but...
but if my observe-er calls set I get a "Query is out of date, you must observe() the query prior to any data modifications'" error I cannot reconcile.
You shouldn't have watch call notify and also have observe call set. Choose one or the other. Otherwise you're setting yourself up for an infinite loop of callbacks.
The code below works for me. The only change I made to your crudify function was to change array.forEach(query, crud.c) to query.forEach(crud.c).
<script type="text/javascript" src="../javascripts/dojo-release-1.9.3-src/dojo/dojo.js"></script>
<script type="text/javascript">
window.stackoverflow = {
crudify: function ( store, query, crud )
{
var result;
if ( !crud )
{
crud = query;
query = store;
store = null;
}
if ( store )
{
query = store.query( query );
}
result = query.observe( function ( row, deleteIndex, insertIndex )
{
console.log("Observed");
var del = ( 0 <= deleteIndex ), ins = ( 0 <= insertIndex );
!del && ins && crud.c && crud.c( row );
del && ins && crud.u && crud.u( row );
del && !ins && crud.d && crud.d( row );
}, !!crud.u );
crud.c && query.forEach( crud.c );
return result;
}
};
require([
"dojo/store/Memory",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/_base/json",
"dojo/domReady!"
], function(Memory, Observable, Stateful, dojo){
var store = Observable(new Memory({ data: [] }));
var rawData = [ { id: 1, data: "A" }, { id: 2, data: "B" }, { id: 3, data: "C" }]
var myQuery = { id : 3 };
rawData.forEach(function (obj, index) {
statefulObj = new Stateful(obj);
statefulObj.watch(function(name, oldValue, newValue) {
console.log("Watched");
store.notify(statefulObj, statefulObj.id);
});
store.put(statefulObj);
});
window.setTimeout(function() {
// this directly triggers the observe() callback
store.notify(store.get(3), 3);
}, 2000);
window.setTimeout(function() {
// this triggers the watch(), which indirectly triggers observe() through notify()
store.get(3).set("data", "Sea?");
}, 4000);
window.setTimeout(function() {
// this calls no callbacks because it doesn't match the query
store.put({ id: 2, data: "Bee" });
}, 6000);
window.setTimeout(function() {
// this update triggers observe()
store.put(new Stateful({ id: 3, data: "See!?!" }));
// note that we didn't set up a watch() on this new object (see below)
}, 8000);
window.setTimeout(function() {
// whoops, this doesn't trigger a callback because we forgot to call watch() above
store.get(3).set("data", "C4");
}, 10000);
window.setTimeout(function() {
// but the observe() callback still works
store.notify(store.get(3), 3);
}, 12000);
window.setTimeout(function() {
// this deletion triggers observe()
store.remove(3);
}, 14000);
stackoverflow.crudify(
store,
myQuery,
{
u: function(obj) {
console.log("Observed update: obj: " + dojo.toJson(obj));
},
c: function(obj) {
console.log("Observed creation: obj: " + dojo.toJson(obj));
},
d: function(obj) {
console.log("Observed deletion: obj: " + dojo.toJson(obj));
}
});
});
</script>