Pass the extended object from the service to the controller within a promise using the .map function

section: I am currently working on extending a JSON object within a service and passing it to a controller. The JSON originally came to the service from another service that makes backend calls. The code is quite intricate, so I've added comments and console.logs for clarity:

    // Retrieve games config object from another service
    gamesConfig: gamesConfigService.gamesConfig(),

    // Prepare the names of game icons. This support function will be executed in the next method
    transformSpace: function(subject) {
        var ensuredSubject = subject.toString().toLowerCase();
        var transformedSubject = ensuredSubject.replace(/ /g, '_');
        return transformedSubject;
    },

    // Add the iconname property to the game config object
    extendGameConfig: function() {

        var that = this;

        this.gamesConfig
        .then(function (response) {

            console.log(response.data); // Successfully logs the JSON data

            response.data.map(function(obj) {

                return new Promise(function(res){
                    angular.extend(obj, {
                        iconname: that.transformSpace(obj.attributes.name) + "_icon.png"
                    });
                });

            });

        }, function () {
            console.log('error');
        });
This code includes a support method transformSpace and a main method that seems to have issues passing data correctly (at least, that's what I think). I am attempting to retrieve this promise in the controller using the following code:
theService.getGamesObj.extendGameConfig()
    .then(function (response) {
        $scope.allGames = response;
        console.log($scope.allGames);
    }, function () {
        console.log('error')
    });
I plan to use the data in the view. However, the current code is not functioning as expected and is returning the following error:

TypeError: Cannot read property 'then' of undefined

Answer №1

I have identified the sections in your code where errors seem to be occurring

extendGameConfig: function() {
    // ***********
    // use => functions, that = this wont be needed
    var that = this;
    // ***********
    // if you want this this function to return something, add a return 
    // this is why you get the 
    // Cannot read property 'then' of undefined error
    // as this function returns undefined
    this.gamesConfig
    .then(function (response) {

        console.log(response.data); // this works and console.log my JSON
        // ***********
        // you're using .map ... and discarding the result! 
        response.data.map(function(obj) {
            // ***********
            // you're creating a promise that never resolves!
            // also, why are you promisifying synchronous code?
            return new Promise(function(res){
                angular.extend(obj, {
                    iconname: that.transformSpace(obj.attributes.name) + "_icon.png"
                });
            });
        });
    }, function () {
        console.log('errror');
    });

Therefore, it is recommended to try the following fixes

extendGameConfig: function() {
    return this.gamesConfig
    .then(response => {
        return response.data.map(obj => {
            return angular.extend(obj, {iconname: this.transformSpace(obj.attributes.name) + "_icon.png"});
        });
    }, function () {
        console.log('errror');
    });

or, an even better approach

extendGameConfig: function() {
    return this.gamesConfig
    .then(response => 
        response.data.map(obj => 
            angular.extend(obj, {iconname: this.transformSpace(obj.attributes.name) + "_icon.png"})
        )
    )
    .catch(function (err) {
        console.log('error', err);
        throw err; // log the error, but you'll probably want to reject this promise so the calling code doesn't think there is success?
    });
}

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 modify the activate_url for django-allauth?

My technology stack includes Django with Django REST framework serving as a backend, and AngularJS on the frontend. For managing users, I have implemented django-rest-auth, utilizing django-allauth for user management. I started off with the demo provided ...

Axios is causing my Pokemon state elements to render in a jumbled order

Forgive me if this sounds like a silly question - I am currently working on a small Pokedex application using React and TypeScript. I'm facing an issue where after the initial page load, some items appear out of order after a few refreshes. This make ...

Loss of precision occurs when converting a BigDecimal value from a JSON

After making a network call, the backend is sending the following data: "uom" : "EA", "qty" : 1.123456789012345678 However, when this information reaches the frontend and is logged using console.log: { qty: 1.1234567890123 ...

A guide to increasing a loop counter in Vue

Having trouble looping through a specific group of objects in a multi-object array? Take a look at the code below: <template> <div> <h1>My Test App</h1> <button v-on:click="getHockeyData">Get Team Data< ...

Differences between REST web services and JSON services

RESTful web services operate on a stateless server where URLs represent resources and utilize HTTP methods like GET, POST, DELETE, PUT for actions. I am considering developing a JSON service layer that relies on server-side state, with URLs representing r ...

Is it possible to implement jQuery events on all elements belonging to a specific class

Hey there, I'm facing a little challenge with my code. Currently, I have a snippet that allows a user using iOS to drag around a <div> with the class .drag on the webpage. Everything works perfectly when there's only one instance of .drag, ...

Problem with sequential promises

import { Observable } from 'rxjs/internal/Observable'; export function createHttpObservable(url: string) { console.log('Url is', url); return Observable.create(observer => { fetch(url) .then(response => { ...

I am currently dedicated to enhancing my background transitions and experimenting with creating smooth fade-ins

I'm almost done with my Weather Forecast page for the FCC challenge. However, I'm not satisfied with how the code for swapping the background works. It just doesn't feel right to me. Unfortunately, I can't figure out how to fix it. Addi ...

Trouble with Displaying HTML Table in Bootstrap 4.3.1 Tooltip

Struggling for hours to set up a custom HTML table in a tooltip box, I finally found that the Bootstrap version solves the issue. Surprisingly, it works perfectly under Bootstrap 4.0.0 but fails under Bootstrap 4.3.1. Could this be a bug or am I overlooki ...

Tips for showing a single table with buttons on display

I am using R markdown and have included multiple tables with buttons, but when I open the file, all tables are displayed at once. How can I ensure only one table is shown upon opening the file? https://i.sstatic.net/NFidf.png <script type="text/ja ...

Combining Framer Motion with Next.js: Resolving conflicts between layoutId and initial props in page transitions

As I work on creating smooth image page transitions using Framer Motion and Next.js with layoutId, I've come across a challenge. Here is my main objective: The home page displays an overview with 3 images When an image is clicked, the other images f ...

Updating the background image without having to validate the cache

I have implemented a basic image slideshow on my website using a simple Javascript function. The function runs every 5 seconds to update the CSS "background-image" property of a div element. While it is functional, I've noticed that each time the func ...

What is the best way to successfully send an object through AJAX once all its updates are completed?

I am experiencing an issue with my JavaScript code within an event: var userData = tableWidget.grid('userData'); console.log(tableWidget.grid('userData')); $.ajax({ "url": "../../server/query.aspx?tableEvent=reordercolumns&tabl ...

Exploring the power of async/await in combination with map or foreach

I am facing a challenge in retrieving multiple product prices from my database. I had initially thought of using the map or forEach methods to iterate through them and add up the prices to a variable as shown below: // Get Total exports.getTotal = (req,re ...

javascript various backgrounds on click

I have implemented a list to allow users to select their top 3 choices, and I am using JavaScript to track these selections and change the background color accordingly. 1st selection -> Green background 2nd selection -> Yellow background 3rd sel ...

What is the process for incorporating a new URL into the routes.js file of a preexisting Node.js project that was developed with locomotive?

module.exports = function routes() { this.root('pages#main'); this.match('/status', 'pages#status'); this.resources('paper'); this.resources('tempform'); this.match('/paper/domain', 'pages#n ...

Having issues with Sencha Touch not initiating in mobile browsers

For quite some time now, I have been developing a mobile app using Sencha Touch 2.1 and conducting tests primarily on desktop Chrome and an iOS PhoneGap / Cordova package. Recently, I made the decision to release it as a "native" app while also offering re ...

Routing in Next.js to create custom URL slugs for usernames, like (site.com/username), is a

I have a requirement to create username pages on my website, where each username will have its own page like site.com/jack The current folder structure I am using is pages > [user] > index.js, but this setup causes issues when someone tries to acces ...

Having trouble with my Express.js logout route not redirecting, how can I troubleshoot and resolve it?

The issue with the logout route not working persists even when attempting to use another route, as it fails to render or redirect to that specific route. However, the console.log("am clicked"); function works perfectly fine. const express = require('e ...

Array with multiple dimensions using commas as delimiters

My array (array[]) contains elements in the format below, separated by a comma: array[0] = abc, def, 123, ghi I want to transform this array into another multi-dimensional array (arrayTwo[]), structured like this: arrayTwo[0][0] = "abc" arrayTwo[0][1] = ...