I am attempting to use an external function call to render my calendar where view settings, events and resources are passed in as JSON function parameters. I have managed to load both events and view settings correctly using the following function but it would be potentially useful to load in the resources in a similar way.
function refreshCalendar(eventsArray, resourceArray, view, startDate) {
calendar.addEventSource(eventsArray);
calendar.addResourceSource = resourceArray; <- This line needs fixing
calendar.changeView(view, startDate);
calendar.render(); }
Related
I'm a beginner in Ionic and Firebase. To learn using ionic+firebase, I'm writing a RandomQuote app to fetch a random entry from Firebase. A reload() method is called when I click a reload button, and the random quote is displayed as expected.
However, I also want the quote to display when the app is loaded, i.e., before I click the reload button. I call the reload() method in the constructor but it doesn't work. I have tried to search for answers on the web but cannot find anything that I could understand. Not sure if I'm searching the wrong keywords or in the wrong domains.
The following is the reload() method that I put in my FirebaseProvider class and called from my home.ts:
reload(){
this.afd.list('/quoteList/').valueChanges().subscribe(
data => {
this.oneQuote = data[Math.floor(Math.random() * data.length)];
}
)
return this.oneQuote;
}
Can anyone give me some hints? Or any pointer to useful books / materials for beginners will also be highly appreciated. Thank you very much.
Data is loaded from Firebase asynchronously. This means that by the time your return statement runs this.oneQuote doesn't have a value yet.
This is easiest to say by placing a few log statements around your code:
console.log("Before subscribing");
this.afd.list('/quoteList/').valueChanges().subscribe(
data => {
console.log("Got data");
}
)
console.log("After subscribing");
When you run this code, the output is:
Before subscribing
After subscribing
Got data
This is probably not what you expected. But it completely explains why your return statement doesn't return the data: that data hasn't been loaded yet.
So you need to make sure your code that needs the data runs after the data has been loaded. There are two common ways to do this:
By moving the code into the callback
By returning a promise/subscription/observable
Moving the code into the callback is easiest: when the console.log("Got data") statement runs in the code above, the data is guaranteed to be available. So if you move the code that requires the data into that place, it can use the data without problems.
Returning a promise/subscription/observable is a slightly trickier to understand, but nicer way to doing the same. Now instead of moving the code-that-needs-data into the callback, you'll return "something" out of the callback that exposes the data when it is available. In the case of AngularFire the easiest way to do that is to return the actual observable itself:
return this.afd.list('/quoteList/').valueChanges();
Now the code that needs the quotes can just subscribe to the return value and update the UI:
reload().subscribe(data => {
this.oneQuote = data[Math.floor(Math.random() * data.length)];
}
A final note: having a reload() method sounds like an antipattern. The subscription will already be called whenever the data in the quoteList changes. There is no need to call reload() for that.
I have two forms of search
POST /search
GET /search?q=q
For POST, I can just use Meteor.call in client.
'submit form': function() {
Meteor.call('search', data......
}
For GET, How can I call Meteor.call in router?
Router.route('/search', {
template: 'ItemList',
data: function() {
return Meteor.call('search', this.params.query); // ???
}
and about the search method, it will not only search database but also search file system.
I don't know how to do the second GET search.
I would suggest not doing the calls in your router. The router is responsible for directing the flow of actions and it would make it more complex if it was also managing all of the data and external resource tracking.
In the template level, you could easily detect the routers params (Router.current()) or have them passed directly from the router in the data section.
Then on rendered you could have the template hit your call function. And then make it reactive with some dependency tracking
You can do Router.current().params.q to get the q variable from url.
You won't need data: function() in the said approach.
From what I have seen using a debugger, calling:
require(["menu/main-menu"], function(util) {
Will load the main-menu.js file, but the function is called before the global code in the required .js file is executed? Is this correct?
If so, what is the best way to have all that code executed before my function is called?
The problem I am trying to solve is I want the code in mani-menu.js to all be in a module. But I can't call any method in that module until the global code in there is executed which creates the module.
I can call a global method in there which then creates everything, but that then requires a global init() method in every .js file (each with a unique name).
What's the best way to handle all this?
Update: There's a more basic question here (maybe). In writing javascript (and I use Sencha Ext JS & TypeScript), I need to create my objects. So when I go to create say my main menu, I want to call a method in my main-menu.js file to get that Ext JS derived menu object I created.
I think all the code in main-menu.js should be in a namespace, including the method I call to get the menu object. Is that correct? In addition, the way most Ext JS code is set up is you have several Ext.define() calls as well as other variable instantiations, and then the function that takes all that, builds the full menu, and returns it. But that requires all that code has executed in main-menu.js before I call it.
Am I approaching this correctly? My experience to date is Java & C# and I may be trying to fit that model incorrectly to javascript.
Let's suppose menu/main-menu.js contains this:
define(function () {
// Module factory function
return [... whatever you want to expose...];
});
And your application does this:
require(["menu/main-menu"], function (util) {
// Require callback.
});
What happens is:
The require call loads menu/main-menu.js.
The define in menu/main-menu.js is executed.
The module factory function (the function passed to define) is executed.
The require callback is executed with the symbol util set to
what the factory function in menu/main-menu.js returned.
As for simulating namespaces, there are multiple ways to do it. For
instance, you can do it like this:
define(function () {
return {
foo: function () {},
bar: function () {},
[...]
};
});
This exports an object with two functions in it. You can then use it
like this:
require(["menu/main-menu"], function (util) {
util.foo();
util.bar();
});
RequireJS also supports a CommonJS-style of defining modules:
define(function (require, exports, module) {
exports.foo = function () {};
exports.bar = function () {};
[...]
});
This is functionally equivalent to the first way I defined the module
earlier: you get the same two functions and you use them in the same
way as I've shown above.
Unfortunately, I can't speak about Ext JS specifically because I don't
use it.
I want to load multiple files to use in D3.js. Queue.js seems to be a nice tool for that. Since d3.js supports more advanced XHR functionalities in v3, I want to load multiple files with Queue.js and show the loading progress, and abort loading of all files on error.
This is how you check the progress and how to use Queue.js: https://github.com/mbostock/d3/wiki/Upgrading-to-3.0
I don't know how to combine these pieces of code.
This is what I have until now.
JSFiddle
I think it is better that there would be a progress event handler on Queue.js, but I don't know how to implement this.
Example code:
queue()
.defer(d3.json, "file1.json") // https://api.github.com/repos/mbostock/d3")
.defer(d3.json, "file2.json")
.progress(function() { console.log(d3.event.loaded/d3.event.total; }) // or use argument?
.error(function(error) { this.abort(); console.log(error); })
.await(function(data) { console.log(data); });
The object returned by queue() in queue.js doesn't have the methods "progress" and "error". Here is a link to the source code: https://github.com/mbostock/queue/blob/master/queue.js.
As queue.js takes an xhr object and uses 'apply' to execute the function, the following workaround worked for me. It involves using the get() method of an xhr object to execute the function.
Sample code:
queue().defer(d3.json("file1.json")
.on("progress", function({console.log(d3.event.loaded);})
.get, /*First argument*/ "error")
.await(function (error, file1_data) {console.log(file1_data);});
Hope this helps.
When I'm in the flash debugger, and I have some callbacks saved, I can see that the functions have a property named savedThis that is very usefull to know where that callback came from.
I'm trying to access that property from code, but for some reason I can't.
callback.savedThis throws an Error because it can't find the property, probable because it's private.
So I tried to add a method to the Function class that would give me access to it:
Function.prototype.getSavedThis = function()
{
return this.savedThis
}
But it gives me the same error about not finding the property, even though I can see it in the debugger.
Is there a way to access it?
Note: I'm not planing on using this in production code, I'm making some classes to help me with debugging by automating some data gathering, and it would be incredible useful to get this information without having to add code to every callback saved informing of the this object.
You can get a reference to a calling function by using the 'arguments.callee' property.
For example:
bar( arguments.callee );
public function bar( caller:Function ) : void { trace( caller ); }