Combining an element in AngularJS

Currently, I am exploring AngularJS and decided to create a simple application using the Steam API as a practice exercise. To achieve this, I have developed a basic Spring Boot Rest service that acts as a reverse proxy for the Steam API, allowing specific calls to be forwarded. At this point, there are two main actions:

/user/ provides a list of Steam IDs. /user/:id/games retrieves data from the following API endpoint:

The response from the API is in the following JSON format:

{  
   "response":{  
      "game_count":3,
      "games":[  
         {  
            "appid":70000,
            "playtime_forever":0
         },
         {  
            "appid":550,
            "playtime_forever":0
         },
         {  
            "appid":274900,
            "playtime_forever":0
         }
      ]
   }
}

My goal is to extract the games array from this JSON object and add it to the respective user. This process needs to be repeated for all users. I've made some progress by utilizing the $resource object and creating the following factories:

angular.module("SAM.Resources", [])
    .factory("UserList", ["$resource",
        function ($resource) {
            return $resource('/user');
        }])

    .factory("GamesList", ["$resource",
        function ($resource) {
            return $resource('/user/:id/games', {
                id: '@id'
            });
        }
    ]);

In my controller, I'm implementing the following approach:

UserList.query(function(response){
    $scope.users = response ? response : [];
    for(index=0; index < $scope.users.length; ++index){
        user = $scope.users[index];
        $scope.users[index].games = GamesList.get({id:user.id});
    }
});

While this setup is close to what I intend to achieve, it currently returns results in the format:

  {
    "id": "76561198119953061",
    "name": "Yuri",
    "games": {
      "response": {
        "game_count": 3,
        "games": [
          {
            "appid": 70000,
            "playtime_forever": 0
          },
          {
            "appid": 550,
            "playtime_forever": 0
          },
          {
            "appid": 274900,
            "playtime_forever": 0
          }
        ]
      }
    }
  }

However, I want to remove the extra layer of games.response.games. While attempting to address this issue, changing it to:

$scope.users[index].games = GamesList.get({id:user.id}).response.games;

resulted in failure since it's a promise and doesn't immediately contain the response object.

I also tried something like

GamesList.get({id:user.id}), function(response){
 angular.extend(user, response);
});

This implementation successfully adds the response to the user object, but the user object is always the last value in the array when the promise resolves.

Therefore, my main question boils down to: How can I enhance my User object with the Games list?

Answer №1

To improve your code, make the following changes:

UserList.query(function(response){
    $scope.users = response ? response : [];
    for(index=0; index < $scope.users.length; ++index){
        user = $scope.users[index];

        (function(index, id){
            GamesList.get({id: id}, function(response){ // Retrieve games from the response
                $scope.users[index].games = response.response.games;
            }));
        })(index, user.id)
    }
});

In the for loop, the value of user keeps changing. By the time the first GameList.get call has a result, the loop would have progressed to the last user.

Enclosing this in an IIFE will create a separate scope for these variables.

Answer №2

for(loop=0; loop < $scope.users.length; ++loop){
    person = $scope.users[loop];
    $scope.users[loop].gameData = GamesList.get({id:person.id}, function(response){
        angular.extend(person, response);
    }));
}

As you iterate through the loop, each user's information will be updated. However, the callback function will only run after the loop is finished, so only the last user data is used.

To prevent this issue, you can utilize an anonymous function within a forEach loop:

$scope.users.forEach(function(person) {
    $scope.users[loop].gameData = GamesList.get({id:person.id}, function(response){
        angular.extend(person, response);
    }));
});

If you wish to avoid having nested objects like user.games.response.games, you should merge the objects differently.

$scope.users.forEach(function(person) {
    $scope.users[loop].gameData = GamesList.get({id:person.id}, function(response){
        person.games = response.games;
        person.game_count = response.game_count;
    }));
});

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 are some effective strategies for reducing excessive re-rendering of React components?

Here is how I am displaying a list of components on the screen: const MessagesContainer = ({ messages, categories, addHandler }) => { const options = categories.map(category => ( { value: category.name, label: category.name } )); ...

Explain what mongoose and Schema are at the beginning, just once

Hello, I am currently working on a Node.js application using Express and MongoDB. In order to utilize MongoDB and schema, I have to define Mongoose and schema in all of my routing JavaScript files. However, I would like to only define them once. As I am ne ...

Updating data in AngularJS using a service to interact with a flat JSON file

Excuse my ignorance, but here's my question: Can a flat JSON file be used in an Angular service to act as a database for CRUD operations? This would only be for basic development purposes. I intend to eventually use Django Rest Framework, Firebase, or ...

Error generated by bash while attempting to utilize DocuSign, cURL, and JSON: "ENVELOPE_IS_INCOMPLETE"

My experience with cURL is a bit limited, but I am currently attempting to run a simple test to replicate the 'basic scenarios' of creating an envelope from a document using the V2 REST API documentation. This involves working with a single-page ...

Triggering a dynamically created event with the onchange event

I'm currently working on creating an input type file, and here is the code I have: var element = document.createElement("INPUT"); element.type = "file"; element.id = "element" + i; $("#media").append("<br>"); $("#media").append("<br>"); $ ...

Updating an AngularJS directive following a service method invocation

My goal is to set up a reusable alert service that can be easily called from anywhere in my application with just: alertService.showAlert('warning', 'something went wrong!'); One example of where I want to use this is after an AJAX ca ...

What could be causing the response from curl_exec() in my web service?

What is causing curl_exec() to return an array in my web service? I set up a web service for sending push notifications with Firebase. Everything functions perfectly except that the server response includes the notification result, even though I did not r ...

If I needed to include extra information within an element for easy retrieval using JavaScript

Using PHP, I have generated a list of products in a <select> element. Each product has a weight that I want to store within each <option> so I can access it later using Javascript. Is there a way to include the weight data directly in the HTML ...

Launching Toasts with Bootstrap 4

I've been working with toasts in Bootstrap 4 and one thing has been bothering me: When I initialize the toast like this: <div class="toast my-3" data-delay="2500"> <div class="toast-header text-dark"> //fill this later &l ...

The ViewChild from NgbModalModule in @ng-bootstrap/ng-bootstrap for Angular 6 is causing the modal to return as

I have successfully integrated ng bootstrap into my project, specifically utilizing the modal module to display a contact form. The form includes input fields for email and message, as well as a submit button. You can find the ngbootstrap module I am using ...

What could be the reason for the empty response in my PATCH request in Javascript?

I am facing an issue with my app that runs Rails in the backend and Javascript in the frontend. The controllers, routes, and CORS are all set up correctly. Both my Post and Get requests work without any problems. However, when I attempt to make a patch req ...

Error: The 'latin-1' codec is unable to encode the character u'u05a0' at position 85 because it is outside the range of 256

Currently, I am facing an issue while trying to input a JSON format file into my database. The problem seems to be related to Unicode values present in the JSON format. If you need more insight on the Unicode error, you can refer to this link: Unicode Er ...

ASP.NET "Data" Error: Trouble Parsing JSON Data on the Front-End

I am currently facing an issue with the configurations on my asmx page. The code is set up like this: using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using System.Web.Script.Serialization; using Syst ...

Is it Unwise to Depend on Props within the useReducer Hook?

Within my App() component, I utilize props named data. This particular component relies on a useReducer hook to manage its state. The reducer function is responsible for determining when to display or hide specific data based on the state. Additionally, it ...

Ajax- priorToSend

To avoid encountering the same error twice, I implemented the use of beforeSend in my code. hasSent = false function submit() { if (!hasSent) { $.ajax({ url: "${createLink(controller:'userInvitation', action:'ajaxUp ...

The `modelName` model cannot be recompiled as it has already been written

Issue with Updating partnerCode Model After Compilation. I have a file called models/partnerCode.js var mongoose = require('mongoose'); var Schema = mongoose.Schema; var partnerCodeSchema = new Schema({ email: String, used: {type: Numb ...

Tips for utilizing multiple components in Angular 2

I am a beginner in angular2 and I am attempting to utilize two components on a single page, but I keep encountering a 404 error. Here are my two .ts files: app.ts import {Component, View, bootstrap} from 'angular2/angular2'; import {events} f ...

The jQuery .next() function is applying a class to each element

I am struggling with adding a class to the <a> elements in my Bootstrap 4 Carousel when the slider changes. Currently, my code successfully adds the class .highlight to the next <a> elements, but it adds it to all subsequent elements. Addition ...

Tips for testing React Final Form's Field Components on a unit level

While developing a form component using the react-final-form library, I encountered a situation where the component started growing in size. To address this, I decided to split it into multiple sub-components - with the parent component containing the < ...

Sending the axios fetched property from the parent component to the child component results in the error message "TypeError: Cannot read property 'x' of undefined"

I've noticed that this question has been asked before, but none of the solutions provided seem to work for my situation. Parent component import axios from "axios"; import { useEffect, useState } from "react"; import Child from &q ...