Utilizing an AngularJS factory to retrieve JSON data from the server

I have a large JSON object in my controller that I want to move to a separate file. Currently, this is how I'm approaching it:

myApp.controller('smController', ['$scope', function($scope) {
  ...
  var stadtmobilRates = {
    classic: {
      A: {
        night: 0,
        hour: 1.4,
        day: 21,
        week: 125,
        km000: 0.2,
        km101: 0.18,
        km701: 0.18
      },
      ...
    }
  };

I've implemented a factory and promises following the guidance provided here on Stackoverflow:

myApp.factory('stadtMobilRates', function($http) {
  var promise = null;

  return function() {
    if (promise) {
      // If we've already requested this data before,
      // return the existing promise.
      return promise;
    } else {
      promise = $http.get('stadtmobilRates.json');
      return promise;
    }
  };
});

myApp.controller('smController', ['$scope', function($scope, stadtMobilRates) {
  var stadtmobilRates = null;
  stadtMobilRates().success(function(data) {
    stadtmobilRates = data;
  });

Now I'm encountering a

TypeError: undefined is not a function
at the
stadtMobilRates().success(function(data) {
line. Why isn't the stadtMobilRates factory being recognized even though I injected it into the controller?

Edit #1: I added the factory name to the array as advised by prawn.

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) {
  var stadtmobilRates = null;
  stadtMobilRates().success(function(data) {
    stadtmobilRates = data;
  });

  console.log(stadtmobilRates);

However, stadtmobilRates is still null?

Edit #2: I created a simplified version of my app on Plunker. It works there. In my full app, which involves different routes, stadtmobilRates remains null. Unfortunately, creating a Plunker for the complete app with routes is not feasible. So, here is the full code on GitHub. The snippet above is from Line 159. I suspect it might be related to my routes?

Answer №1

Make sure to include the name of the factory in the array when passing it. The array should consist of strings followed by the function itself, keeping it in sync with the parameters in the function declaration. This allows the injector to know which services to inject into the function.

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) {

EDIT

Here's how I would handle it... When using routes, I prefer using resolve to load and store data once. In the $routeProvider, I would adjust the smController part as follows...

 when('/sm', {
      templateUrl: 'partials/sm.html',
      controller: 'smController',
      resolve:{
              load:function(stadtMobilRates){
                  return stadtMobilRates.LoadData();
          }
    }).

I've also made some changes to the factory

myApp.factory('stadtMobilRates', function ($q, $http) {
var mobilRates = null;

function LoadData() {
    var defer = $q.defer();
    $http.get('stadtmobilRates.json').success(function (data) {
        mobilRates = data;
        defer.resolve();
    });
    return defer.promise;
}

return {
    GetData: function () { return mobilRates ; },
    LoadData:LoadData
}
});

This route will now call the LoadData function in the factory before loading. Once the data is loaded, it resolves the promise so the LoadData function is only called once. After resolving the promise, it proceeds to load the view.

In your controller, you can simply retrieve the data by calling the GetData function

myApp.controller('smController', ['$scope', 'stadtMobilRates', function($scope, stadtMobilRates) 
{
     var stadtmobilRates = stadtMobilRates.GetData();
});

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

What mechanism does the useState() function utilize in React to fetch the appropriate state object and function for a functional component when employing the state hook?

Currently focusing on deepening my understanding of the useState hook in react. I have a question regarding how useState retrieves the state object and modifier function specific to each functional component when it is called. What I'm wondering is w ...

I am facing an issue where reducing the size of the renderer is causing my click events to be offset. What steps can I

At the moment, my rendered model (which is grey in color) stretches across the entire width of the html page with the mesh centered within that width. I want to reduce this width but when I do so, the click event on the model seems to be misaligned. Three. ...

Managing additional components in request JSON when communicating with DialogFlow, previously known as Api.ai

My current challenge involves enhancing the information sent in a JSON request from my application to DialogFlow. While I am familiar with triggering events to send data calling an intent through the method described in Sending Parameters in a Query Reques ...

Executing a function when a webpage loads in Javascript

I have created a responsive website using Twitter Bootstrap. On my site, I have a video displayed in a modal that automatically plays when a button is clicked. Instead of triggering the function with a button click, I want the function to be called when ...

Navigating through JSON arrays with Node.js

I have been given the task of iterating through a complex JSON file that contains an array of JSON objects. I am finding it difficult to access the array object within the JSON file. Specifically, I need to access the "class-name" object from the JSON f ...

Flowtype: Utilizing type hints for class-based higher order component

I am currently working on typehinting a higher-order component (HOC) that adds a specific prop to a passed Component. The code snippet looks like this: // @flow import React, { Component } from 'react'; import type { ComponentType } from 'r ...

Positioning pop-up windows using Javascript and CSS techniques

In my web application, there is a search field that allows users to enter tags for searching. The window should pop up directly below the search field as shown in this image: Image I am trying to figure out how the window positioning is actually d ...

What steps can I take to guarantee that a directive's link function is executed prior to a controller?

Our application features a view that is loaded through a basic route setup. $routeProvider .when('/', { template: require('./views/main.tpl.html'), controller: 'mainCtrl' }) .otherwise({ re ...

Is there a way to prevent items in Dropbox from being selected?

Here is an example of my HTML element: <select class="form-control" ng-model="current.data.sites" ng-options="item.Id as item.Description for item in current.lookups.siteReg | filterByIdArray: current.data.sites"> <option value="">--Data-- ...

Error encountered: iPad3 running on iOS7 has exceeded the localStorage quota, leading to a

Experiencing a puzzling issue that even Google can't seem to solve. I keep getting the QuotaExceededError: DOM Exception 22 on my iPad3 running iOS7.0.4 with Safari 9537.53 (version 7, WebKit 537.51.1). Despite turning off private browsing and trying ...

Error in Java DynamoDB Streams Lambda: Unable to convert a floating-point value to a date in type `java.util.Date` (token `JsonToken.VALUE_NUMBER_FLOAT`)

I've been working on an AWS Lambda function that listens for DynamoDB Streams events and then updates an Elasticsearch index accordingly. I decided to leverage the Quarkus framework for my code, and after doing some research, I came across a helpful r ...

Error occurred due to an invalid element type with the imported React component

Using a component imported from an npm package in two different apps has resulted in unexpected behavior. In one app, the component functions perfectly as expected. However, in the other app, an error is raised: Element type is invalid: expected a string ...

Combining two lists in immutable.js by flattening and zipping

When faced with two immutable lists, such as: const x = [5,6,7]; const y = [x,y,z,w]; Is there a straightforward method to combine/interleave them in order to obtain: const z = [5,x,6,y,7,z,w]; ...

There seems to be an issue with FastAPI not sending back cookies to the React

Why isn't FastAPI sending the cookie to my React frontend app? Take a look at my code snippet: @router.post("/login") def user_login(response: Response, username :str = Form(), password :str = Form(), db: Session = Depends(get_db)): use ...

Error: Uncaught ReferenceError: d3 is undefined. The script is not properly referenced

Entering the world of web development, I usually find solutions on Stack Overflow. However, this time I'm facing a challenge. I am using Firefox 32 with Firebug as my debugger. The webpage I have locally runs with the following HTML Code <!DOCTYP ...

Is there a way to enhance the functional purity by creating a single function that subscribes and returns a

I'm currently developing a project that involves receiving humidity data from a raspberry pi sensor connected to a backend. Within my Angular Component, I am aiming to display this data in a functional and pure manner. However, I have some doubts rega ...

Make sure to enable contentEditable so that a <br> tag is inserted

When using a contentEditable, it automatically wraps words to create a new line once the width of the editable area is reached. While this feature is useful, I am facing an issue when parsing the content afterwards as I need it to insert a <br> tag ...

Encountered an issue while trying to assign a value to the 'value' property on an 'HTMLInputElement' within a reactive form

When I upload a picture as a data record, the image is sent to a server folder and its name is stored in the database. For this editing form, I retrieve the file name from the server and need to populate <input type="file"> in Angular 6 using reacti ...

I am experiencing issues with the ng-dropdown-multiselect library and it is not functioning

Check out this awesome library for creating dropdown menus using angularjs and twitter-bootstrap-3 at: . I am trying to implement the examples provided. In my html, I have: <div ng-dropdown-multiselect="" options="stringData" selected-model="stringMod ...

How do I return a <div> element to its initial state after JavaScript has made changes to it?

So, I have this situation where a DIV contains a form. After users submit the form successfully, I want to replace the form with a simple message saying "everything is good now". This is how I currently do it: $("#some_div").html("Yeah all good mate!"); ...