update ui-grid row with new data, replacing existing rowdata

I have integrated angular ui grid into my project and added a button on the left of each row. Clicking this button should add the respective row to the cart. Since duplicate rows can be added, I am trying to make each row unique by using milliseconds. However, every time I click the cart button on row one, it overwrites the previous entry. I attempted initializing a new array, but that did not solve the issue.

For a working demo, please refer to the JSFIDDLE link provided below.

JS:

var myApp = angular.module('myApp', ['ui.grid']);

myApp.controller('myCtrl', ['$scope', '$filter', function($scope, $filter) {

var productData = {
    "Products": [{
        "TagLevel1": null,
        "ProductName": "Carrot",
        "ProductCode": "car-001",
        "IsSelected": null,
        "ClientLineId": null,
        "Active": true
    }, {
        "TagLevel1": null,
        "ProductName": "Cucumber",
        "ProductCode": "cuc-001",
        "IsSelected": null,
        "ClientLineId": null,
        "Active": true
    }, {
        "TagLevel1": null,
        "ProductName": "Cabbage",
        "ProductCode": "cab-001",
        "IsSelected": null,
        "ClientLineId": null,
        "Active": true
    }, {
        "TagLevel1": null,
        "ProductName": "Lettuce",
        "ProductCode": "let-001",
        "IsSelected": null,
        "ClientLineId": null,
        "Active": true
    }]
};

var actionTemplate = '<div style="text-align:center;vertical-align:middle;line-height:35px;"><button id="{{row.entity.ProductId + \'_AddToCartBtn\'}}" title="Add to cart" ng-class="(row.entity.IsSelected == true ? \'iconBtnClicked iconBtnClick fa fa-cart-plus fa-2x\':\'iconBtn iconBtnClick fa fa-shopping-cart fa-2x\')" ng-click="grid.appScope.AddToCart(row.entity, $event)" /></div>';

  $scope.gridOptions = {
        rowHeight: 35,
    showGridFooter: false,
        enableFiltering: false,
        enableColumnMenus: false,
        columnDefs: [
            { field: 'IsSelected', name: 'IsSelected', width: '85', displayName: 'ACTION', enableSorting: false, enableFiltering:false, cellTemplate: actionTemplate },
            { field: 'ProductCode', name: 'ProductCode', width: '200', displayName: 'PRODUCT CODE'  },
      { field: 'ProductName', name: 'ProductName', width: '800', displayName: 'PRODUCT NAME' },
        ],
    onRegisterApi: function(gridApi) {
            $scope.gridApi = gridApi;
        }
    };

  $scope.init = function() {
    $scope.ProductViewModel = productData;
    $scope.gridOptions.data = $filter('orderBy')($scope.ProductViewModel.Products, "ProductCode", false);
    $scope.ProductViewModel.Products = [];
  };


    $scope.AddToCart = function(rowData, event) {
        rowData.IsSelected = true
        rowData.ClientLineId = new Date().getUTCMilliseconds();
        console.log('ClientIdUsed:' + rowData.ClientLineId);

        $scope.ProductViewModel.Products.push(rowData);
        console.log('PVM.Products: ' + JSON.stringify($scope.ProductViewModel.Products));
    };

  $scope.init();
}]);

Any suggestions or assistance would be highly appreciated.

View the fiddle demo for reference: JSFIDDLE. The array output is logged in the console.

UPDATE

To resolve the issue, I adjusted the function as follows:

$scope.AddToCart = function(rowData, event) {
    $scope.ProductViewModel.Products.push({"TagLevel1":null,"ProductName":rowData.ProductName, "ProductCode":rowData.ProductCode, "IsSelected": true, "ClientLineId": new Date().getUTCMilliseconds(), "Active":rowData.Active, "$$hashKey":rowData.$$hashKey });
    console.log('PVM.Products: ' + JSON.stringify($scope.ProductViewModel.Products));
};

Is there a more efficient and maintainable way to achieve this?

EDIT

The final array output in the console (after clicking the cabbage row 4 times) should appear like this:

[{"TagLevel1":null,"ProductName":"Cabbage","ProductCode":"cab-001","IsSelected":true,"ClientLineId":142,"Active":true,"$$hashKey":"uiGrid-0007"},{"TagLevel1":null,"ProductName":"Cabbage","ProductCode":"cab-001","IsSelected":true,"ClientLineId":285,"Active":true,"$$hashKey":"uiGrid-0007"},{"TagLevel1":null,"ProductName":"Cabbage","ProductCode":"cab-001","IsSelected":true,"ClientLineId":376,"Active":true,"$$hashKey":"uiGrid-0007"},{"TagLevel1":null,"ProductName":"Cabbage","ProductCode":"cab-001","IsSelected":true,"ClientLineId":962,"Active":true,"$$hashKey":"uiGrid-0007"}]

*Make note of the unique ClientLineIds generated

Answer №1

The array in $scope.ProductViewModel.Products is not the same as the one in $scope.gridOptions.data.

Take a look at the updated solution:

$scope.init = function() {
    $scope.ProductViewModel = productData;
    $scope.ProductViewModel.Products = $filter('orderBy')($scope.ProductViewModel.Products, "ProductCode", false);
    $scope.gridOptions.data = $scope.ProductViewModel.Products;
};

Check out the fixed fiddle here

Answer №2

I resolved the issue by creating a new object and iterating through the keys and values to add them to the new object every time there was a click event.

$scope.AddToCart = function(rowData, event) {
    rowData.IsSelected = true;
    var newObj = {};
    $.each(Object.keys(rowData), function(i,v){
        if(v === "ClientLineId")
        newObj[v] = new Date().getUTCMilliseconds();
        else if(v === "IsSelected")
        newObj[v] = true;
        else
        newObj[v] = rowData[v];
    });
    $scope.ProductViewModel.Products.push(newObj);
    console.log(JSON.stringify($scope.ProductViewModel.Products));
};

Check out FIXED FIDDLE

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

Make a duplicate of the webpage on your own device

Can webpages be automatically saved to the client side after a server-side request, without the need for manual saving? I am managing multiple clients that display a series of webpages from the server. Each page contains various media files like images an ...

Retrieving items from an array within a MongoDB aggregate operation based on specific criteria for fields at the same level

After analyzing the data provided, I am seeking a way to retrieve objects from the od array based on specific conditions. Additionally, I aim to extract the em and name fields as well. Although I lack extensive knowledge on MongoDB's aggregate functi ...

Caution: The update depth has reached its maximum limit. Demonstrating the BubbleSort algorithm using React

Recently, I have been attempting to visualize bubble sort using React. Although the sorting and animation functionalities are working smoothly, once the sorting is completed, React starts throwing errors. https://i.sstatic.net/a8tPC.png In my efforts to ...

Uh-oh! The module "side-channel" cannot be found. An error occurred in the loader with code 936 when trying to run the command "npm start"

During the execution of npm start to view my React app, I encountered the following error: > react-scripts start node:internal/modules/cjs/loader:936 throw err; ^ Error: Cannot find module 'side-channel' Require stack: - C:\Users&bs ...

Can you confirm if this email address is legitimate?

"Sophie Dupont"@sample.com While diving into RFC 5321 in an attempt to fully grasp the concept of a valid email address, I find myself overcomplicating things unnecessarily. This topic has been on my mind lately. i.e., within a quoted str ...

Save information entered into dynamically created input boxes in an array

I am currently working on a project to develop a website that generates timetables. However, I have encountered a roadblock in my progress. My issue lies in dynamically generating user-selected text boxes for subjects and faculties using a for loop. Unfor ...

Use Jquery to smoothly scroll to the top offset of

I've been successfully utilizing jquery ScrollTo from https://github.com/balupton/jquery-scrollto, but I'm interested in incorporating the "offset top" add-on. Has anyone had experience setting this up? I'm not quite sure how to implement it ...

What is the best way to align the left div with the right div?

Here's the challenge: I want to make the left div stretch to the height of the right div https://i.sstatic.net/R3MCY.png and here's the desired outcome https://i.sstatic.net/UAXWC.png Currently, I'm implementing this using bootstrap < ...

Initiate a standalone backend service during frontend testing

I am facing a challenge with my current setup where I have an API project running at localhost:8000 connected to a test database, along with a front-end Angular app running at localhost:9000. After each front-end test case run, I need to reset the database ...

Which syntax highlighting tool does Google Chrome utilize?

In the Chrome/Chromium inspector, there is a unique syntax highlighter that displays black text while scrolling and highlights after a period of time. This feature differs from Firefox Web Developer Toolbar's highlighting method, which may take longer ...

Dynamically generated Angular directive fails to run

Check out this Plnkr sample: [http://plnkr.co/edit/jlMQ66eBlzaNSd9ZqJ4m?p=preview][1] While this may not follow the standard Angular approach, I am currently dealing with restrictions imposed by third-party libraries. My aim is to dynamically create an A ...

Why isn't my router link clickable? What mistake did I make?

import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import Products from '../views/Products.vue' const routes = [ { path: '/', name: 'Home', ...

It is necessary to enclose the $http request within a $timeout in order to receive data

I'm running into an issue where, whenever I click the button inside my component, the $http call is made but I don't see the response in the console. Oddly enough, if I uncomment the $timeout function, the data does appear in the console. Here&a ...

Setting up a node application on Heroku by organizing the client and server components into distinct directories

I've spent hours researching, but I still can't fully grasp this concept. My app is set up with the client built using Vue-cli running on port 8080 from a folder called client, and the server runs on port 8081 from a separate folder named server ...

Having trouble with the express-stormpath login feature for users who have authenticated with their email?

As I run a basic node.js/Express server with express-stormpath for user authentication, everything runs smoothly without email verification. However, email verification is essential for various reasons; nevertheless, my email-verified users face issues whi ...

Importing a 3D Model Using Three.js

I've been trying to import a 3D model by following tutorials. I managed to successfully import using A-Frame Tags, but encountering issues with Three.js. The code snippets are from a tutorial on YouTube that I referred to: https://www.youtube.com/watc ...

Utilizing CSS nth-child on dynamically generated HTML in Angular

Ensuring that the columns are floated to the left without large gaps between rows is my current challenge. Here's the HTML structure I'm working with: <div class="row hide-for-small"> <div ng-repeat="module in modules"> ...

Insert a variety of images onto the page at the exact position where the user has

Looking to create a script that selects a random image from an array and displays it at the current mouse position. Additionally, you can click elsewhere to add a new image, allowing you to cover the entire page with random cat images if desired. docum ...

Using Jquery to apply a class if the height of an image is larger than its width

Can someone assist me with a jQuery question regarding adding classes to images? I am currently working on a DEMO on codepen.io The issue I'm facing is that the JavaScript isn't adding a class to the image if the height is greater than the widt ...

Instead of receiving the actual values from the array, I am seeing the memory addresses of the array elements (Output:[I@59494225) in Scala. In the following code snippet, I anticipate the output to be (2

Here, the task is to compare the elements of arrays a(i) and b(i), updating the scores accordingly. If a[i] is greater than b[i], a is given 1 point. If b[i] is greater than a[i], b is awarded 1 point. object MyWizard extends App { def compar ...