Error message: Unspecified service injected

I am currently working with 2 separate javascript files for my project. One is being used as a controller, while the other serves as a service. However, when I attempt to inject the service into the controller and access its function, an error message pops up.

var app = angular.module('currencyConverterModule', []); 
app.factory('currencyConverter', function() {

var localToINR = [
{USD: 0.015},
{GBP: 0.011}
];

var convertToLocalCurrency = function (amount, localCurrency) {
return amount * localToINR[localCurrency];
}
  
return { convertToLocalCurrency };
});

var app = angular.module('cartModule', ['currencyConverterModule']); 
app.controller('cartController', ['$scope', 'currencyConverter', function ($scope, currencyConverter){

$scope.SelectedCountry = '0'; 
$scope.localCurrency = function(amount, currencyConverter) {
currencyConverter.convertToLocalCurrency(amount, $scope.SelectedCountry);
}

$scope.Products = [
{name: 'TV', price: $scope.localCurrency(30000), quantity: 1},
{name: 'Fridge', price: $scope.localCurrency(35000), quantity: 1},
{name: 'AC', price: $scope.localCurrency(40000), quantity: 1}
];

$scope.Countries = [
{name: 'India', currency: 'INR', currencySymbol: '&#8377'},
{name: 'United States', currency: 'USD', currencySymbol: '$'},
{name: 'England', currency: 'GBP', currencySymbol: '£'}
];

$scope.getCartValue = function () {
var total = 0;
for (var i = 0; i < $scope.Products.length; i++) {
total = $scope.Products[i].price * $scope.Products[i].quantity;
}
return total;
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body>
<div ng-app="cartModule" ng-controller="cartController">
<table ng-hide="SelectedCountry == '0'">
<tr>
<th>Product</th>
<th>Price Per Unit</th>
<th>Quantity</th>
<th>Total Price</th>
</tr>
<tr ng-repeat="product in Products">
<td ng-bind="product.name">
</td>
<td ng-bind="product.price | currency : '&#8377'"></td>
<td>
<input type="number" ng-model="product.quantity" min="0" max="100">
</td>
<td ng-bind="product.price * product.quantity | currency : '&#8377'"></td>
</tr> 
<tr>
<th colspan="3">Total</th>
<th ng-bind="getCartValue() | currency : '&#8377'"></th>
</tr>
</table>

<select ng-model="SelectedCountry">
<option value="0">Select your country</option>
<option ng-repeat="country in Countries" ng-value="country.name" ng-bind="country.name"></option>
</select>
</div>
</body>

TypeError: Cannot read property 'methodName' of undefined

Service

var app = angular.module('currencyConverterModule', []);
app.factory('currencyConverter', function() {

    var localToINR = [
        {USD: 0.015},
        {GBP: 0.011}
    ];

    var convertToLocalCurrency = function (amount, localCurrency) {
        return amount * localToINR[localCurrency];
    }

    return { convertToLocalCurrency };
});

and Controller

var app = angular.module('cartModule', ['currencyConverterModule']);
app.controller('cartController', ['currencyConverter', function ($scope, currencyConverter){

    $scope.SelectedCountry = '0';
    $scope.localCurrency = function(amount, currencyConverter) {
        currencyConverter.convert(amount, $scope.SelectedCountry); //Error here
    }

    $scope.Products = [
        {name: 'TV', price: $scope.localCurrency(30000), quantity: 1},
        {name: 'Fridge', price: $scope.localCurrency(35000), quantity: 1},
        {name: 'AC', price: $scope.localCurrency(40000), quantity: 1}
    ];  

    $scope.Countries = [
        {name: 'India', currency: 'INR', currencySymbol: '&#8377'},
        {name: 'United States', currency: 'USD', currencySymbol: '$'},
        {name: 'England', currency: 'GBP', currencySymbol: '&#163;'}
    ];  

    $scope.getCartValue = function () {
        var total = 0;
        for (var i = 0; i < $scope.Products.length; i++) {
            total = $scope.Products[i].price * $scope.Products[i].quantity;
        }
        return total;
    }
}]);

I have attempted switching the order of including these files in the view, but that did not resolve the issue. Can someone help me identify what I am doing incorrectly?

In my HTML file, I reference the following JS files:

<script src="../Script/angular.js"></script>
<script src="../Services/currencyConverter.js"></script>
<script src="../Script/cartController.js"></script>

Answer №1

You forgot to include $scope in your code,

app.controller('cartController', ['$scope','currencyConverter', function ($scope, currencyConverter)

The correct method name is convertToLocalCurrency, not just convert

currencyConverter.convertToLocalCurrency(amount, $scope.SelectedCountry); 

EDIT

Your function parameter name 'currencyConverter' is causing undefined errors. Consider renaming it or removing it if unused,

$scope.localCurrency = function(amount, currency) {
    currencyConverter.convertToLocalCurrency(amount, $scope.SelectedCountry);
}

VIEW WORKING DEMO

I have made some modifications to the service to return the factory with the necessary methods as shown below:

var app = angular.module('currencyConverterModule', []);
app.factory('currencyConverter', function() {
  var dataFactory={};
    var localToINR = [
        {USD: 0.015},
        {GBP: 0.011}
    ];

    dataFactory.convertToLocalCurrency = function (amount, localCurrency) {
        return amount * localToINR[localCurrency];
    }

    return dataFactory ;
});

Answer №2

The function $scope.localCurrency mistakenly includes two parameters:

app.controller('cartController', ['$scope', 'currencyConverter',
  function ($scope, currencyConverter){    
    $scope.SelectedCountry = '0';
    $scope.localCurrency = function(amount) {
        currencyConverter.convertToLocalCurrency(amount, $scope.SelectedCountry);
    }

The factory currencyConverter is injected in the controller construction function rather than in the local scope function.

The DEMO

var app = angular.module('currencyConverterModule', []);
app.factory('currencyConverter', function() {

var localToINR = [
{USD: 0.015},
{GBP: 0.011}
];

var convertToLocalCurrency = function (amount, localCurrency) {
return amount * localToINR[localCurrency];
}
 
return { convertToLocalCurrency };
});

var app = angular.module('cartModule', ['currencyConverterModule']);
app.controller('cartController', ['$scope', 'currencyConverter', function ($scope, currencyConverter){

$scope.SelectedCountry = '0';
$scope.localCurrency = function(amount) {
currencyConverter.convertToLocalCurrency(amount, $scope.SelectedCountry);
}

$scope.Products = [
{name: 'TV', price: $scope.localCurrency(30000), quantity: 1},
{name: 'Fridge', price: $scope.localCurrency(35000), quantity: 1},
{name: 'AC', price: $scope.localCurrency(40000), quantity: 1}
];

$scope.Countries = [
{name: 'India', currency: 'INR', currencySymbol: '&#8377'},
{name: 'United States', currency: 'USD', currencySymbol: '$'},
{name: 'England', currency: 'GBP', currencySymbol: '&#163;'}
];

$scope.getCartValue = function () {
var total = 0;
for (var i = 0; i < $scope.Products.length; i++) {
total = $scope.Products[i].price * $scope.Products[i].quantity;
}
return total;
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body>
<div ng-app="cartModule" ng-controller="cartController">
<table ng-hide="SelectedCountry == '0'">
<tr>
<th>Product</th>
<th>Price Per Unit</th>
<th>Quantity</th>
<th>Total Price</th>
</tr>
<tr ng-repeat="product in Products">
<td ng-bind="product.name">
</td>
<td ng-bind="product.price | currency : '&#8377'"></td>
<td>
<input type="number" ng-model="product.quantity" min="0" max="100">
</td>
<td ng-bind="product.price * product.quantity | currency : '&#8377'"></td>
</tr> 
<tr>
<th colspan="3">Total</th>
<th ng-bind="getCartValue() | currency : '&#8377'"></th>
</tr>
</table>

<select ng-model="SelectedCountry">
<option value="0">Select your country</option>
<option ng-repeat="country in Countries" ng-value="country.name" ng-bind="country.name"></option>
</select>
</div>
</body>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Ionic framework alongside Ionic View to display a beautiful background image

How can I display a full background image in Ionic 1.2? -hooks -platfroms -plugins -resources -scss -www -css -img -js -lib -templates ... Currently, I have the following HTML structure: <ion-view id="login" hide-nav-bar="true"> ...

Having trouble displaying a popup dialog box in ASP.NET using JavaScript

I am trying to implement a popup dialog box in ASP.NET using JavaScript, but it's not working as expected! Below is the code I am using: <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal< ...

Encountering issues with setting up the <title> and <meta> tags in a Next.js

I recently developed a dynamic web page. It works perfectly fine when I test it on localhost; the title and meta tags are visible without any issues. However, after building the project, I noticed that the view page source does not display the title and me ...

Tips for moving an element to the end of an array

Patients' data is stored in the MongoDB database, and all patients are mapped through on the frontend to display a list. An additional boolean value indicates whether a patient is archived or not. If a patient is archived, it should be displayed at th ...

Tips for displaying an edit action icon when hovering over specific text

Looking for a way to display or hide the edit icon when hovering over specific text? Take a look at this snippet of HTML code: <ul> <li> <a id="pop" href="javascript:;;" data-content="test Desc" data-id="123"> &l ...

Executing a Python script in Django and transferring its output to a JavaScript file

Getting Started with Django What I'm Looking For: 1 - Execute a Python Script 2 - Pass data to a JavaScript file I'm unsure if the sentence I've constructed is technically accurate in terms of Django. Below are the JavaScript and Python ...

Why should <template> be used in Vuetify?

Exploring the possibilities of Vuetify 2.0 in my current project has led me to dive into the v-stepper component, designed for displaying progress through numbered steps. In the example provided in the playground, I noticed the use of the <template> ...

Nested JavaScript function expression

In this JavaScript example, the snippet provided is for educational purposes and does not include validation. After defining the variable 'isBetween' within the buildBoundDetector() function, it raises questions about how passing a number through ...

Do you need to define a schema before querying data with Mongoose?

Is it necessary to adhere to a model with a schema before running any query? And how can one query a database collection without the schema, when referred by the collection name? This scenario is demonstrated in an example query from the Mongoose document ...

ng-class not displaying the correct results

Within my form, I have a condition where if $isvalidate is true, the button receives the class 'disable-reg-btn'. Here is an example: ng-class="{{reg_form.$invalid ? 'disable-reg-btn' : ''}}" However, when I view the page in ...

Ways to integrate PHP MySQL with NodeJS and SocketIO

Currently, I am working on developing a chat application. I have successfully implemented features like creating accounts, logging in, selecting, viewing, and more using PHP MySQL. Now, I am venturing into the Instant Messaging aspect by utilizing NodeJS a ...

Execute an Angular factory AJAX request with each change in route

I operate a factory where I utilize a function called getExpenseList that performs an ajax call to fetch data from the expense table. Currently, I have two routes set up - one for listing expenses and another for adding new expenses. However, whenever I n ...

deactivating image mapping on mobile media screens

I'm looking to disable my image map on mobile screens using media queries. I've attempted to include some javascript in the head of my html file, but I encountered an error: <script src="http://code.jquery.com/jquery-1.11.3.min.js"></s ...

Easier JavaScript for numerous HTML elements

I am an aspiring JavaScript learner seeking advice. Currently, I am working on a website that features numerous items with multiple images for each. I am utilizing JQuery to display a larger image when the user hovers over a thumbnail image. My query is ...

Sending colored output from stdout to grunt's output stream

Having trouble creating a custom grunt task that runs mocha tests and displays colored output? I'm running into an issue where grunt is stripping out the colors from the mocha command's output. Here's the code for the grunt task: var exec = ...

Vue Router configuration functions properly when accessed through URL directly

I need guidance on how to handle the routing setup in this specific scenario: Below is the HTML structure that iterates through categories and items within those categories. The <router-view> is nested inside each category element, so when an item i ...

Including a pfx certificate in an Angular $http request

My current challenge involves utilizing an external API located at https://example.com/. Upon attempting to access this API, a prompt appears requesting a certificate. Fortunately, I possess the necessary .pfx file or it may be stored in my keychain as a . ...

Deleting specialized object using useEffect hook

There's a simple vanilla JS component that should be triggered when an element is added to the DOM (componentDidMount) and destroyed when removed. Here's an example of such a component: class TestComponent { interval?: number; constructor() ...

The element 'Component' cannot be utilized as a JSX component since its type 'ReactElement<any, any> | Component<{}, any, any>' is not a valid JSX element

I'm currently facing an issue while running "yarn build" and/or "npm run build" on a repository. The error persists for both commands. My goal is to build and deploy this code to an AWS environment, but I am stuck at resolving the errors that indicate ...

Determine if a SQL column exists following a SELECT statement

I have a query that I need help with: let selectQuery = "select * from mainTable where username = '"+ username + "'"; In my code, I am trying to make sure that childtable2id exists in the table. Here is what I have so far: for (let i = 0; i & ...