AngularJS Get current factory/service name - javascript

Ola!
I was just playing around with angular's factories and services and I just noticed
that I can't get the current name of the factory/service.
At least I couldn't get any resources about that.
For example so its a bit more clear I have a factory, like this;
.factory('GuessImAFactory', [function() {
var factoryName = this.yadayada.name; //<- This actually doesn't work,
//if you haven't guessed
//<--Some other code goes here-->
return something;
}])
So the question does anyone know the trick how to get the name of it?

I don't think this is possible. In callback function you can't get actual instance of factory since you are defining it right in that place. In other works, it's not yet created.
However, simple workaround for this would be to hard code it.. Since you probably won't have dynamic factories, you could just simply say
var factoryName = 'GuessImAFactory';
and use it if needed.

Try this one: factoryObject.__proto__.constructor.name

Related

Vanilla JS - hoisting a querySelected variable to Window

I've been researching and trying different solutions to this literally all day.
** EDIT: regarding duplicate post: As I wrote below, a set timeout function has been attempted and successful around the function call. Please, before you close my question, atleast ask that what you’re describing as a duplicate hasn’t already been attempted… or in this case. INCLUDED in my original post. I’m not looking for cred, I’m looking for help. **
I have a reusable function takes in 3 params:
What to wrap,
wrap in what type of element
and the id of the new wrapping element (so I can control access it later.)
Here's a codeSandbox version to help you help me! https://codesandbox.io/s/queryselector-to-globe-jbffk0?file=/index.html
Goal: I'd like to include a querySelector within the function that takes in the id to eliminate the extra step, to ensure the selector is defined after the item is created, and to keep a cleaner code-base. The problem is I keep fighting between a function that's surrounded by parens...
Var wrap = (function(params){...})(window); to potentially give global scope to the queryselector(object ref) I'm trying to create, and a standard es6 function I'm more familiar with... Var wrap = (params) => {...};
import "./styles.css";
const item = document.querySelector(".item");
var wrap = (function (toWrap, wrapper, id) {
wrapper = wrapper || document.createElement("div");
wrapper.setAttribute("id", `${id}`);
toWrap.parentNode.appendChild(wrapper);
// Non-working auto id something to
// window.id = document.querySelector(`${id}`);
return wrapper.appendChild(toWrap);
})(window);
// How can I "store the window.id" just as if it were manually written right here in global scope?
wrap(item, "div", "itemadded");
Note: the window thing I read at: http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
Like I said, I can provide more working code/attempts to show I've made a ton of effort if anyone is wondering.
PS, I'll definitely mark the answer and give upvotes for help.
Thanks in advance!
If your still reading, I've tried simplifying even further, adding a timeout function to ensure that the function takes in toWrap correctly... idk what else to try... :(

Strange javascript behaviour - error unless 'classes' are defined in correct order

I have a very strange problem with javascript and easel js.
I am using the easel.js library and am already fairly far into the construction of a project using it.
I am attempting to have a 'class' (I know they aren't technically classes in javascript but I will use this terminology for lack of a better word) inherit the Shape class from easel js, and then have another class inherit that. So it would be something like this:
easeljs.Shape --> MenuButton --> BuildingButton
The code I am using looks like this:
BuildingButton.prototype = Object.create(MenuButton.prototype);
BuildingButton.prototype.constructor = BuildingButton;
function BuildingButton(){
MenuButton.call(this);
}
MenuButton.prototype = Object.create(createjs.Shape.prototype);
MenuButton.prototype.constructor = MenuButton;
function MenuButton(){
createjs.Shape.call(this);
}
The problem is that I get the following error with this code:
Uncaught TypeError: undefined is not a function
easeljs-0.7.1.combined.js:8439
(line 8439 is pointing to the initialize() function in the Shape() constructor).
now here's the strange thing. If I change the order of the definitions so that the sub class is defined second and not first, it works fine!
MenuButton.prototype = Object.create(createjs.Shape.prototype);
MenuButton.prototype.constructor = MenuButton;
function MenuButton(){
createjs.Shape.call(this);
}
BuildingButton.prototype = Object.create(MenuButton.prototype);
BuildingButton.prototype.constructor = BuildingButton;
function BuildingButton(){
MenuButton.call(this);
}
This is very confusing as I can't seem to figure out why on earth this is happening. I could just make sure I define them in the correct order and leave it be, but I have all my 'classes' in different source files which are then strung together by grunt, which does so alphabetically.
Also, I feel like I may have a big gap in my knowledge of javascript (or maybe easel.js I'm not sure what exactly is causing this behaviour).
Thanks in advance for your help and I hope the question makes sense!
MenuButton.prototype = Object.create(createjs.Shape.prototype);
…
BuildingButton.prototype = Object.create(MenuButton.prototype);
These two statements have a clear dependency and need to be executed in the correct order (for the function declarations the order is irrelevant if placed in the same scope/file, but if in different files they need to be loaded in the correct order obviously).
I have all my 'classes' in different source files which are then strung together by grunt, which does so alphabetically
That's not a good idea. You should use some build tool/script that allows the declaration of dependencies.
Read this to clear things out: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
In first example you try to inherit from nothing, since MenuButton.prototype is not yet defined. To make it work just add MenuButton.prototype = new createjs.Shape.prototype(instead of Object.create() wich shouldn't be used anymore) to instantiate it first before you can you use it. Your first code is like you are willing to eat a banana before having one.

Why does Meteor template helper not return variable in context?

For some reason, this doesn't work at all.
{{user_slugged username}}
The {{username}} is a variable available to the template. However, it gives me a null / undefined value in the helper.
Here is my helper code
UI.registerHelper('user_slugged', function(username) {
... other stuff... return things.
}
The issue I am having is when I try something like this {{user_slugged 'Hello'}} it does everything right and returns what is expected.
However, when I try {{user_slugged username}} it doesn't seem to work even though I can easily display {{username}} in that same line of code.
Which seems really odd, now I'm thinking the way to send parameters to handlebars helpers might have changed in Meteor 0.8.0. If so, it'd be great if someone could point me into the right direction or give me an answer to this question.
EDIT: To clarify I am able to use {{username}} in the same line as {{user_slugged username}} so something like this works
{{username}}
username is an object property that is available in the template and at the point where I am trying to send it in as a param to the helper.
I am not sure why this is happening (maybe there is a global helper username?), but you should be able to fix it easily by writing
{{user_slugged ./username}}
instead of
{{user_slugged username}}
The dot always means the current data context, so there is no way that the rendering engine will get confused about it.

AngularJS - Continuosly watch over a collection

I'm trying to build a real watcher for a collection in my app and, at first, I thought that Angular would provide me everything I needed.
I mean, I had the $watch, both shallow and deep. and the $watchCollection, a $digest cycle that loops over my $scope-exposed variables through the dirty checking mechanic and triggers all the watchers...
Great! What else could I need?
Wrong!
Turns out that $watchCollection gets triggered only at the first change of the watched variable...
And that's it for the mighty watchers... why???
After a reality check, I realized that I needed some kind of horrible loop to check this collection, or else I had to implement some sort of callback to do this, whenever the var gets modified.
Anybody knows how this can be done in the cleanest way possible?
Important note:
I don't why, but it seems that some horrific bug in my code was gnawing my ankles...
Now that I've fixed it, both $watchCollection(expr, foo) and $watch(expr, foo, true) works as expected...
I was mislead by this SO post , in which an user comments:
[...] I don't see anything in your code that makes the subsequent requests (to check for new messages). Where does that happen?
I took his comments as proof of my hypothesis... my bad!
I'm leaving this question as a memento
I'm pretty sure a regular $watch will do this if you utilize the 3rd parameter (objectEquality). This will check if the objects are equal and not just references.
So, you can use something like this:
$scope.$watch('prop', function(value) {
// do something
}, true);
The true value tells Angular to compare objects instead of references.
The documentation for this feature is with scope.
below solution is bit of an hacking solution and should only be used if $watchCollection does not work. rather than watching on the array, watch on json
$scope.$watch(function() {
return angular.toJson($scope.array);
},
function() {
// watch logic
}
I am using above solution to watch on multiple arrays like below:
$scope.$watch(function() {
return JSON.stringify([$scope.array1, $scope.array2]);
},
function() {
// watch logic
}
you can user either of JSON.stringify or angular.toJson.

EmberJS - Adding a binding after creation of object

I am trying to bind a property of an object to a property that's bound in an ArrayController. I want all of this to occur after the object has already been created and added to the ArrayController.
Here is a fiddle with a simplified example of what I'm trying to achieve.
I am wondering if I'm having problems with scope - I've already tried to bind to the global path (i.e. 'App.objectTwoController.objectOne.param3') to set the binding to. I've also tried to bind directly to the objectOneController (which is not what I want to do, but tried it just to see if it worked) and that still didn't work.
Any ideas on what I'm doing incorrectly? Thanks in advance for taking the time to look at this post.
So in the example below (I simplified it a little bit, but same principles apply)... The method below ends up looking for "objectOne" on "objectTwo" instead of on the "objectTwoController".
var objectTwoController: Em.Object.create({
objectOneBinding: 'App.objectOne',
objectTwoBinding: 'App.objectTwo',
_onSomething: function() {
var objectTwo = this.get('objectTwo');
objectTwo.bind('param2', Em.Binding.from('objectOne.param3'));
}.observes('something')
});
The problem is that you can't bind between two none relative objects. If you look in the "connect" method in ember you will see that it only takes one reference object (this) in which to observe both paths (this is true for 9.8.1 from your example and the ember-pre-1.0 release).
You have few options (that I can think of at least).
First: You can tell the objects about each other and in turn the relative paths will start working. This will actually give "objectTwo" an object to reference when binding paths.
....
objectTwo.set('objectOne', this.get('objectOne');
....
Second: You could add your own observer/computed property that will just keep the two in sync (but it is a little more verbose). You might be able to pull off something really slick but it maybe difficult. Even go so far as writing your own binding (like Transforms) to allow you to bind two non-related objects as long as you have paths to both.
_param3: function(){
this.setPath('objectTwo.param2', this.getPath('objectOne.param3');
}.observes('objectOne.param3')
You can make these dynamically and not need to pre-define them...
Third: Simply make them global paths; "App.objectOneController.content.param3" should work as your binding "_from" path (but not sure how much this helps you in your real application, because with larger applications I personally don't like everything global).
EDIT: When setting the full paths. Make sure you wait until end of the current cycle before fetching the value because bindings don't always update until everything is flushed. Meaning, your alert message needs to be wrapped in Ember.run.next or you will not see the change.

Categories

Resources