Angular Underscore Cannot read property 'find' of undefined - javascript

I'm trying to return the object with a specific "ID" from the json service. I can see the objects in my console log but any attempt to iterate or use underscore _find gives me "undefined"
var metaresult = _.find($scope.results.results, function(rw){ return rw.id == $scope.answer1 });
gives me this error:
TypeError: Cannot read property 'find' of undefined
at k.$scope.metaResult (https://evening-taiga-2443.herokuapp.com/js/controllers/MainController.js:173:21)
Here is my factory:
app.factory('results', ['$http', function($http) {
return $http.get('js/services/results.json')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
any my json structure:
{
"results": [
{
"id": "a"
},
.... and so on
EDIT: So the issue seems to be dependency. I tried using ng-underscore instead and I'm loading as follows:
<script src="js/ng-underscore.min.js"></script>
then the app.js
var app = angular.module("quizApp", ['720kb.socialshare', 'ngUnderscore']);
Then in my controller
app.controller('MainController', ['$scope', 'quiz', 'results', function($scope, quiz, results, underscore)
typing "underscore" into console gives me:
Uncaught ReferenceError: underscore is not defined
EDIT: Figured it out just need to use lodash

var metaresult = _.find( ...
TypeError: Cannot read property 'find' of undefined
This error means that javascript didn't know what is _. _ is undefined and when you do _.find then error is generated. It seems you're not loading libraries properly. Kindly make sure you have added the underscore js module. Once underscore is loaded, _ will reference to the js module and you will be able to use all the methods.

Once get the libs to load correctly, it should be:
var metaresult = _.findWhere($scope.results.results, { id: $scope.answer1.id });
http://underscorejs.org/#findWhere

_ would be referring to either lodash or underscore which are both javascript utility libraries. I would suggest that you take a look at bower which is a package manager for front end libraries and make sure that you both have the necessary files in your project and also that they are being referenced in your HTML.
I would personally recommend that you use lodash instead of underscore as it is essentially a drop in replacement and offers performance benefits. That being said, there is absolutely no reason to use an angular module wrapper in based on the code that you've shown here. Simply downloading lodash and including it in your HTML will make it available for use inside your controller without having to worry about any module dependencies or controller injection.

Related

AngularJS Dependency injection failure - Drag&Drop

I'm trying to implement a Drag&Drop system.
I've found an amazing one :
http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/nested
Github:
https://github.com/marceljuenemann/angular-drag-and-drop-lists/issues
Now, it says load "dndLists" into my Dependency -
So my app looks like this:
var app = angular.module('clarus_app', ['ngRoute'], ['dndLists'] );
but then it crashes.
angular.js:116 Uncaught Error: [$injector:modulerr] Failed to instantiate module clarus_app due to:
Error: [ng:areq] Argument 'fn' is not a function, got string
No idea what I'm doing wrong.
The controller the page uses looks like this:
app.controller("logCtrl", ['$scope','$location','$http', function($scope, $location, $http){
Any help? any idea?
Thanks in advance.
You have 2 different array arguments for module dependency and only want one array containing all dependencies
Change
var app = angular.module('clarus_app', ['ngRoute'], ['dndLists'] );
To
var app = angular.module('clarus_app', ['ngRoute','dndLists'] );
// ^^ single array of dependent module names

why can't omit module dependency in angular.module when define component

The main moduleapp.js:
angular.module("myApp",["phoneList"]);
and I follow the tutorial to make a sperate component module named phoneList
angular.module("phoneList")
//^ omit the empty bracket here, cause no dependency needed
.component('phoneList', {
templateUrl: 'template/phone-list.html',
controller: function (){
this.phones = [
{name: "iphone", snippet: "designed by apple"},
{name: "nexus", snippet: "phone that could explode"}
]}
});
but it will complain that:
angular.min.js:6 Uncaught Error: [$injector:nomod] http://errors.angularjs.org/1.6.1/$injector/nomod?p0=phoneList
at angular.min.js:6
at angular.min.js:25
at b (angular.min.js:24)
at Object.module (angular.min.js:25)
at phone-list.js:5
When I add an empty [] back:
angular.module("phoneList",[])
.component(//balabla)
things will work just fine. I checked the API Reference, it demonstrate that the dependency is optional thus could be omitted.
So what cause the problem?
According to the documentation,
angular.module(name, [requires], [configFn]);
If specified then new module is being created. If unspecified then the
module is being retrieved for further configuration.
It means you need to pass an empty array []. To make it work without any dependency module, you can use it as
angular.module("phoneList",[])
Update
if the module is already declared you do not have to pass the dependencies again. So you can use your component/controller/service/factory as
angular.module('phoneList').controller(...)...
Once you have the module defined you can refer to it without the second argument. The first time you do.
So...
angular.module('app',[ dependencies... ]);
angular.module('app').controller(...)...
would be correct.
This is because passing an array in the second argument tells angular to create a new instance of the module with all the dependencies mentioned. If you do not have any dependencies you have to pass a empty array in order to create a new module.
By omitting this parameter you ask angular to retrieve the existing module. And, in your code you do not have a module previously named phoneList. That is why it is giving you the error.

Angular constant : config

I'm working on an Angular app and I'd like to create a config file. From what I read, I should use angular constant.
So I tried to create my constant. From what I read (here, here and also here + doc), it seems quiet easy.
Here is my file :
angular.module('app')
.constant('config', {
routers : {
Commandes: 'some_data',
Prestations: 'some_data',
Interventions: 'some_data'
},
serverPath : 'some_data'
});
As I read it's possible to inject it in a service, I tried to use it in a factory and to display it :
app.factory('myFactory', [function(config) {
console.log('config : '+config);
return // something;
}]);
But the config appears "undefined" (no error here, just console.log things).
It seems that I'm not gettong it, but what the hell did I miss ?
To retrieve the constant from the factory service you have to use the whole path as you defined in your config file.
In your example:
config.serverPath
config.routers.Commandes
// etc...
Another thing is that you need to define the constants as dependencies inside the square brackets:
app.factory('myFactory', ['config', function(config) {
console.log('config : '+config);
return // something;
}]);

Override dependency object prototype in angularjs

I have a set of angular $resource defined in a module called 'App.API' in a single file which I cannot touch because it is generated. (With loopback-angular, a tool to generate angular $resource from server side model definitions)
Let's take the Product dependency as en example, later in the app, I want to override its prototype, like this :
module('App.NewModule', ['App.API']).run(['Product', function(Product) {
Product.prototype.getTitle = function() {
return 'Product name is ' + this.name;
};
// From now on I can use p.getTitle() on every Product $resource
});
It works.
The thing is, I have many different files, each containing modules, and I am experiencing a dependency injection issue : I can access the getTitle function inside NewModule, but not inside other modules.
Question : How can I override a dependency object prototype and make it available to other modules ?
I tried to define the prototype functions in this way instead, thinking that Product prototype would be modified. Maybe not early enough :
module('App.API').run(['Product', function(Product) {
Product.prototype.getTitle = function() {
return 'Product name is ' + this.name;
};
});
It does not work : using getTitle in another module (using App.API/Product as a dependency) on a Product instance still throws a undefined is not a function error, even while Product object is correctly injected.
Actually, I just messed up the dependency definitions / orders.
I have three files :
app.js for module App (dependant on module App.API)
api.js for module App.API
product.js containing Product prototype
As stated in the question, I was doing :
// in product.js
module('App.API').run(['Product', function(Product) { ... }]);
// in app.js
var appModule = module('App', ['App.API']);
But the App.API module was defined in another file, which is a bit messed up because you never know for sure which one will load first, unless dealing with in in the js loader and loosing parallel downloads.
So I explicitly specified the modules and dependencies, at the expense of adding more dependency to declare in my app (but it works and is more stable) :
// in product.js
module('ApiProduct', ['App.API']).run(['Product', function(Product) { ... }]);
// in app.js
var appModule = module('App', ['App.API', 'ApiProduct']);
Note : In my first attempt, I defined the prototype in a new module in a .config() block, but it was not working, maybe because App.API services were not loaded yet. With .run() it works and my getTitle prototype is available everywhere I need Product provider.

Undefined object being passed via Requirejs

I'm using Requirejs to load the JavaScript in our web app. The issues is that I'm getting an undefined object being passed to a module which, when used in other modules, is instantiated perfectly fine.
OK, here's the setup. My main.js file which requirejs runs on startup:
require.config({
baseUrl: "/scripts",
paths: {
demographics: "Demographics/demographics",
complaints: "Complaints/complaints",
}
});
require(["templates", "demographics", "complaints", "crossDomain"], function (templates, demographics, complaints) {
"use strict";
console.log("0");
console.log(demographics === undefined);
demographics.View.display();
});
A lot of the config has been stripped to just the core files in this problem.
Here's Demographics.js:
define(["ko", "templates", "complaints", "globals", "underscore"], function (ko, templates, complaints, globals) {
// Stuff removed.
return {
View: view
};
});
and Complaints.js
define([
"demographics",
"ko",
"templates",
"complaints",
"visualeffects",
"globals",
"webservice",
"underscore",
"typewatcher",
"imagesloaded"],
function (demographics, ko, templates, complaints, visualeffects, globals, webservice) {
"use strict";
console.log("1");
console.log(demographics === undefined);
return {
View: view
};
});
The problem is this - in Complaints.js the demographics parameter passed via the define config is undefined. The console log out tells me that "demographics === undefined" is true.
However, when the main.js file executes, the demographics parameter passed to it is not undefined, it is, as expected, an instantiated object.
Now I'm stuck since I can't see why in complaints.js that demographics variable is undefined. Can anyone spot what I'm missing please?
You have a circular dependency. The demographics module depends on complaints and complaints depends on demographics. As per the documentation:
If you define a circular dependency (a needs b and b needs a), then in this case when b's module function is called, it will get an undefined value for a.
The solution, if you can't remove the circular dependency, is to asynchronously require one of the two modules within the other on demand (say when the view is instantiated instead of when the module that defines the view is executed). Again, the docs cover this topic fairly well.
Another case is when you accidentally type require instead of define when defining a module, took me some time to notice this.
I had a similar problem. In my case, when defining a module, I'd written:
define('some_dependency', ...
instead of
define(['some_dependency'], ...
Another possible reason is implementing the module's interface (AMD, CommonJS), but forgetting to return anything. I just did that.
I just encountered another reason:
define(function () {
return {};
}()); // <-- notice the '()' typo.
This "typo" causes no JS errors for this one and can make it confusing to figure out especially in a complicated application with many potential circular dependancies.
The reason, of course, is the "typo" is valid JS that simply calls the function you define thereby passing its result to define() rather then the function as intended.
One other possible reason that may look obvious in hindsight is an error in your module's code. In my case, I was trying to get an attribute from an undefined variable. The error is logged in the console, but for some reason I was not seeing it/mistaking it for the undefined module error.

Categories