Creating a fresh instance of an Object from a Service that leverages the $resource

I have been enhancing my existing code to improve its functionality by creating two objects for interacting with a RESTful API.

Before, I utilized $http to retrieve the data and return the promise. I would then add some actions using .then and repeat the process by sending additional requests for more data. This resulted in nested $http queries which I want to avoid if possible.

My goal is to have a service (or a factory) that allows me to configure different query parameters and another object for processing and displaying the response.

Here is the current implementation:

var solr1 = angular.module('solr', ['ngResource']);

solr1.run(function(){
    console.log("Module Loaded");
});

solr1.service('solrser', function($resource,solrresult) {
    console.log("In Solrser")
    this.serverurl = 'url';
    this.res = $resource(this.serverurl);

    this.query = function (p) {
        this.res.get(p).$promise.then(function(d) {
         return solrresult(d);
     });
    }
});

solr1.factory('solrresult',function() {
 return function(a) {
  this.data = a;
  this.ready = 0;

  console.log("In Factory")

  this.getdocs = function() {
   console.log("Getting Data")
   console.log(this.data);
   return this.data.docs;   //this is line 9
  }

  return this;
 }});

Controller implementation:

app.controller('app1cont', ['$scope', 'solrser', 'solrresult', function($scope,solrser,solrresult){
    console.log("Start");
    var res = solrser.query({'q':'potato'});
    console.log(res)
    console.log(res.getdocs())
}]);

The output produced is as follows:

Module Loaded solr_module.js:5
In Solrser solr_module.js:9
Start main_controller.js:6
undefined main_controller.js:9
TypeError: Cannot read property 'getdocs' of undefined
    at new <anonymous> (.........../main_controller.js:10:21)
    at Object.e [as invoke] (https://code.angularjs.org/1.3.1/angular.min.js:36:365)
    at F.instance (https://code.angularjs.org/1.3.1/angular.min.js:75:91)
    at https://code.angularjs.org/1.3.1/angular.min.js:58:287
    at s (https://code.angularjs.org/1.3.1/angular.min.js:7:408)
    at G (https://code.angularjs.org/1.3.1/angular.min.js:58:270)
    at g (https://code.angularjs.org/1.3.1/angular.min.js:51:172)
    at g (https://code.angularjs.org/1.3.1/angular.min.js:51:189)
    at https://code.angularjs.org/1.3.1/angular.min.js:50:280
    at https://code.angularjs.org/1.3.1/angular.min.js:18:8 angular.js:11339
In Factory solr_module.js:25

It seems that the factory gets created after the controller continues its execution. What might be the issue here?

Answer №1

It seems like there is a timing issue at play here.

app.controller('app1cont', ['$scope', 'solrser', 'solrresult', function($scope,solrser,solrresult){
    console.log("Start");
    var res = solrser.query({'q':'potato'});
    console.log(res)
    console.log(res.getdocs())
}]);

The problem arises when calling solrser.query() as it operates asynchronously to retrieve the data. This means that the res variable will not contain any actual data until the promise is resolved within the "solrser" service. To address this issue, consider modifying your code like so:

solrser.query({'q':'potato'},function(res) {
    console.log(res); 
    console.log(res.getdocs()); 
});  // Alternatively, you could use promises for this...

Furthermore, the way you handle the response inside the solrser service appears to be unconventional.

    this.query = function (p) {
    this.res.get(p).$promise.then(function(d) {
     return solrresult(d);
 });
}

Using return within the promise handler may not yield the desired results. It would be more effective to use a callback or resolve a deferred object. Consider the following approach instead:

    this.query = function (p,callback) {
    this.res.get(p).$promise.then(function(d) {
     callback(solrresult(d));
 });
}

Alternatively, you can utilize promises like this:

this.query = function (p) {
    var defer = $q.defer();
    this.res.get(p).$promise.then(function(d) {
     defer.resolve(solrresult(d));
 });
    return defer.promise;
}

Another option is to pass the get(p).$promise through.

UPDATE:

Since this action is asynchronous, you must use either a promise or a callback. Consider one of the following approaches:

    app.controller('app1cont', ['$scope', 'solrser', 'solrresult', function($scope,solrser,solrresult){
    var res = solrser.query({'q':'potato'},function() {
        res.getDocs();
    });
}]);

Alternatively, you can directly use a callback:

    app.controller('app1cont', ['$scope', 'solrser', 'solrresult', function($scope,solrser,solrresult){
    solrser.query({'q':'potato'},function(res) {
        res.getDocs();
    });
}]);

Answer №2

I've noticed a couple of missing semicolons in your code:

console.log("In Solrser")

should be

console.log("In Solrser");

There is also a missing semicolon here:

console.log("Getting Data")
console.log("In Factory")

Furthermore, there are missing semicolons in your controller as well. This could be the reason why your code isn't working as expected.

To prevent issues like missing semicolons, I recommend using the JSHint plugin in your IDE.

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

How can I retrieve the selected items from a Listbox control?

Currently, I am working on an ASP.NET application using C#. One of the features in my project involves a Grid View with a Listbox control. The Listbox is initially set to be disabled by default. My goal is to enable and disable this control dynamically bas ...

AngularJS allows for filtering unique values per key and retrieving only the checked items

I am working with an angular object and need to display its records with filtering and sorting functionalities. Additionally, I want to show the unique values per key within the object using checkboxes. I have successfully implemented the record display ...

Is there a way to assign the chosen option from a dropdown list to an input field in Vue 3?

I am working with a list that is returned from an API request. I have a text input field where I can search for items in the list, and the results are displayed dynamically as I type. My goal is to be able to select an option from the list and display the ...

Utilize drag and drop functionality to interact with an HTML object element

I am struggling with a div that contains a PDF object and draggable text: <html> <head> <script> function allowDrop(ev) { ev.preventDefault(); } function drop(ev) { alert("DROP"); } </script> </head> <body> <di ...

Tips for sending an HttpResponse and extra information through Ajax on Django

I am facing a challenge where I need to merge two AJAX requests together. The initial request retrieves HTML content: def ajax_get_html(request): if request.is_ajax() and request.method == "POST": context = { ... } ...

What steps should I follow to generate a table using Ajax and Javascript when a button is clicked?

After spending hours following various tutorials and exploring previously asked questions, I am struggling to make this work. My HTML page looks like this: <!DOCTYPE html> <html> <head> <link type="text/css" rel="styleshee ...

Sending Data from Clicked Button to Another Component as a Prop

I am struggling to figure out how to pass a value that is set inside a button to a child component. Essentially, I want the value of the clicked button that displays a percentage to be passed as a prop value. This prop value should update depending on whic ...

Reaching out to a particular individual with a message

In my coding dilemma, I am trying to make a bot send a message every minute to a particular user, not all users. The struggle is real! guild.members.cache.forEach(member => { setInterval(() => { member.send('hello').catch(error =&g ...

The issue encountered during a POST request in Postman is a SyntaxError where a number is missing after the minus sign in a JSON object at position 1 (line 1

Running my API in a website application works flawlessly, but encountering SyntaxError when testing it in Postman - specifically "No number after minus sign in JSON at position 1" (line 1 column 2). The data is correctly inputted into the body of Postman a ...

The datetime picker feature in AngularJS ui-grid was malfunctioning

AngularJS project grid requires a datetime picker for filtering. To achieve this, I have integrated the angular-bootstrap-datetimepicker-directive. Now, the filter text box displays the datetime picker. However, changing the date does not trigger the fil ...

The JavaScript Autocomplete feature fails to clear suggestions when there is no user input detected

After watching a tutorial on using Javascript with Autocomplete and a JSON file, I implemented the code successfully. However, I encountered an issue: When I clear the input field, all results from the file are displayed. I've tried adding code to cl ...

The JavaScript function modifies the value stored in the local storage

I'm in the process of developing a website that requires updating the value of my local storage when certain JavaScript functions are executed. Currently, I have this code snippet: localStorage.setItem('colorvar', '#EBDBC2'); I&ap ...

Innovative computations that change in real-time according to the data at

The tale. My quest involves the intricate task of computing product costs based on a multitude of variables. Although my current system operates flawlessly through PHP functions, I am eager to enhance the user experience by incorporating Ajax functionalit ...

Executing getJSON requests in perfect synchronization of time

For my weather project, I have two JSON requests to make. The data from the first request is needed in order to personalize the second request for the user. The first request retrieves the latitude and longitude of the user, which are then required for the ...

ReactJS state not being updated due to a nested Axios call

Attempting to fetch data from nested axios calls, successfully retrieving responses from both calls. Struggling to update the prize_pool value within the second axios call. Any assistance would be greatly appreciated. getAllLeague() { axios.get(BA ...

Managing window popups using WDIO - tips and tricks

Having some trouble handling a facebook auth dialog popup through webdriverio. Struggling to target the email and password fields for the facebook signup process. Below is the code in question: it('redirects after signup', () => { browse ...

Glistening: sending reactiveValues to conditionalPanel

Is it possible to pass a reactiveValues to the condition of a conditionalPanel? If so, what is the correct method? Below is my attempt in the UI.R file for the conditionalPanel: conditionalPanel(condition = "values.cond == 0", etc. I have defined values ...

SSI stands for Server Side Includes, a feature that allows

I have multiple versions of the same HTML page, each with only one hidden variable that is different. This variable is crucial for tracking purposes. Now, I am exploring options to rewrite this by incorporating a HTML file with a hidden variable. Here is ...

"An issue arises when using req.body and res.render as the values retrieved are

Encountering an unusual problem - when using req.body to transmit form input to another page, the data is properly displayed when a single word is used in the input field (e.g. "FullName"). However, when there is a space, such as in the example "Full Name" ...

Generate a new entity using a previously imported model with A-Frame

I have successfully imported a house model in .gltf format. I am now trying to extract the floor object from this model and turn it into its own individual a-frame entity for future reference. This is necessary so that I can designate the floor as the coll ...