Angularjs duplicating (briefly) ng-repeat list while making new insertions in the bank

Asked

Viewed 696 times

6

I’m working with an application where in a view I own the product register of a company, or its customers, suppliers, etc. Each view meets a specific area, but each view works with diverse data and data flow, like adding new items, deleting and updating.

The problem I’ve noticed is that when the view has many items, when executing an addition, where it is necessary to make a reload from the list, in order to enter the new data with its respective bank id, there is a "duplicate" of the entire list for a brief moment. Roughly speaking, I insert a new client, he does the reload from the list, apply the whole list to the end of the list that is already on view only to remove the old list.

The code I’m using has no secret, it has $http simple of POST and GET (my backend is controlled by PHP) as in the example:

Ctrl.js

//Chamada automática
    function getProduto() {
        factProdutos.getProdutos().then(function (res) {
            vm.produtos = res;
        }); 
    };

//Chamada da view
    vm.addProduto   = addProduto;

//Function - Produtos
    function addProduto(id) {
        var data = {id_empresa:id};
        $http.post('php/mainFile.php?action=addProduto', data).then(
            function(res) { getProduto(); },
            function(err) { alert(feedbackError); }
        );
    };

Factory.js

function _getProdutos() {
    return $http.get("php/getFile.php?action=getProduto").then(
        function(res) { return res.data;},
        function(err) {alert(feedbackError);}
    );  
};

To make the deletion or update no problem, because I do the process in the Database without having to reload the information, Angularjs takes care of doing this in the view. The same occurs to remove a product from the list, just using the $filter and delete the array element.

The problem even occurs when making a new insertion, because I need id to perform future processes. I’ve read about using the same $filter logic for deletion, but instead of removing, adding the new data.

But how to identify the new data? Or compare the new list loaded with the list currently in my view? Or, this is the best way to do this optimization, or is there a better method?

This is not a mistake, but an optimization of the data flow.

  • Your action addProduto (server) cannot return the ID?

  • Yes, but in some cases it returns a few more fields. For example, the product has reference with a company and a section, so it will come with a few more arguments.

  • In similar situations I maintain the collection of items in a specialized service (empresasService, Clientesservice) and coordinate merge of the object returned with the collection already present in memory. My views receive only references to the collection.

  • Any suggestions on how to merge this into my data stream @Onosendai? Suggestions are welcome. I value the convenience/agility of the code to maintain a pre-set standard by me.

  • It depends a lot on your model, @Celsomtrindade - I, for example, keep the reference of the object being manipulated at the moment, and in the return of the appropriate method (PUT, DELETE, etc.) I decide the action to be taken. I expose the collection from the service, as a property, and map it directly in the Controller.

  • @Onosendai Any tips/models on how to do this? Because never a service (except Factory) especially for this type of treatment. Which may actually be more useful than I think, because if there is a possibility to keep a 'cache' of that list, I don’t need to reload it every time I access a particular view. That would be possible?

  • Sure - give me a few minutes to write an example.

  • No problem, in your time, it’s not so urgent. As I said, it’s just optimization, learning. = D

Show 3 more comments

1 answer

4


One of the possible ways to avoid this artifact (content duplication) is to use a service to manage your collections, and use a Observer Pattern to receive update notifications.

(This demo generates content on the console; on Chrome, use F12 to open development tools and track content.)

The steps would be as follows:

  • Implement Factories to access your application’s REST endpoints (one for collection, one for individual items).
  • Implement a service that consumes the two factories mentioned above, store the result of operations and coordinate CRUD operations;
  • Allow consumers to subscribe to receive updates.

In the following example, the library Nyanjs automatically generates the collections userCollectionFactory and userItemFactory, and consumes them in service userDataService.

The controllers SampleController and SampleController2, in turn, receive service injection userDataService and subscribe for updates via method register. One allows the deletion of objects with even id, and another of objects with odd id. The service coordinates operations and announces content changes.

If you need to generate more test entries, use the following URL: http://www.mockapi.io/#/mocks/565515f70c4bde110041bff0

var app = angular.module('NyanNG', ['ngNyanStack']);

app
    .config([
        'nyanStackProvider', '$httpProvider',
        function ( nyanStackProvider, $httpProvider) {

            nyanStackProvider
                .setup({
                    RestPrefix: 'http://565515f70c4bde110041bfef.mockapi.io/data',
                    Authenticate: false,
                    PluralDescriptor: '{ScopeDescriptor}',
                })
                .module('user', {
                    RootPrefix: "data",
                    collectionName: 'User',
                    useLookupQuery: true,
                    useLocatorQuery: true,

                });

            $httpProvider.defaults.useXDomain = true;
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
        }
    ]).run([
        'nyanStack', function (nyanStack) {
            nyanStack.start();
        }
    ]);
angular.module('ngNyanStack')
    .controller('SampleController', function ($scope, userDataService) {

        $scope.svc = userDataService;

        var localUpdate = function () {
            $scope.data = userDataService.data;
        };

        userDataService.register(localUpdate);

    })
    .controller('SampleController2', function ($scope, userDataService) {

        $scope.svc = userDataService;

        var localUpdate = function () {
            $scope.data = userDataService.data;
        };

        userDataService.register(localUpdate);

    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-resource.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script src="https://rawgit.com/bucknellu/Nyan/ffb7f828938ebeac31ea47f433064bd44552227c/Samples/REST/ng/res/nyan.js"></script>

<table ng-app="NyanNG">
  <tr>
    <td>
      <div ng-controller="SampleController">
        Controller 1

        <p ng-repeat="i in data">
          {{i.id}} - {{i.name}} <button ng-if="!(i.id % 2)" ng-click="svc.remove(i.id);">Delete</button>
        </p>


      </div>
    </td>
    <td>
      Controller 2
      
      <div ng-controller="SampleController2">

        <p ng-repeat="i in data">
          {{i.id}} - {{i.name}} <button ng-if="(i.id % 2)" ng-click="svc.remove(i.id);">Delete</button>
        </p>


      </div>
    </td>
  </tr>
</table>

  • In fact the logic and the idea are excellent. In my current project will not serve, but I have seen an excellent use for others that I already have. However, it was a good response to aggregate. It only bothers me that it is necessary to use external libraries.

  • 1

    @Celsomtrindade Disclaimer - I am the author of the library. Feel free to read the source code and study the flow, and it is always a pleasure to help!

  • 1

    Yes, it makes it easier. What I mean is that many of them have a lack of documentation or a lot of tightness in their use. But as I said, it will be useful in future projects, where I will still begin to develop. In this particular case it did not serve because the project already has a workflow. But the knowledge was excellent.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.