0

Seems that the current website is asp.net web forms calling web api, I am converted to Angular calling Web api. The thing I am noticing is that I need to scrub the data.

How should I go about doing this?
Conditionals in the Html ?

example of old website output

Device Status      Staged       Archived
-----------------------------------------
   Unactivated       None        002,003,001 
   New Device        None        None

MY Angular /html output

Device Status      Staged       Archived
-----------------------------------------
   3                null        [002,003,001] 
   1                null        []
  1. I need to convert the numbers to meaningful Device Status
  2. Seems I need to ALWAYS get rid of []

I thought about in Javascript ... as that is probably better than doing it in Html with angular

Thoughts?

How to do it either way , best practice?

Sample Data

{
 "Devices": [
  {
  "DeviceId": "00022B9A000000010001",
  "StagedManifestIdList": [],
  "PendingManifestId": null,
  "PendingTimeStamp": "0001-01-01T00:00:00",
  "ManifestIdList": [
    "00000002",
    "00000001",
    "00000003"
  ],
  "DeviceStatus": 3,
  "Aid": "oAAABTUAAg==",
  "DKiIndex": "DKi00000002",
  "Sha": "R2tiZRQgY/iohXZt5O4HaQwtVe/adWU2VOcKaelJ3Us=",
  "DefaultPayload": "C:\\ProgramData\\\\Payloads\\M4PayloadAuto.xml"
},
........
]
}

Data $http call

Where does let statement go?

let result.statuses = ['Old Device', 'New Device', 'Activated', 'Unactivated'];

 function DeviceController($http, $scope){
        var vm = this;
        var dataService = $http;
        //dataService.get("/api/Product")

        vm.devices = [];
       deviceList();

      function deviceList() {
           $http.get(_url)
             .then(function (result) {
             vm.devices = result.data.Devices;   
           },
           function(error) {
                console.log('error');
           });

2 Answers2

0

Without posting actual data you have, I am assuming you get an array back like the following:

[
    { status: 3, archived: [002, 003, 001] },
    { status: 1, archived: [] }
]

In order to display the status somewhere you obviously need a lookup for the correct description, for example:

let statuses = ['Old Device', 'New Device', 'Activated', 'Unactivated'];

With this data, you have a few options for how to display the data. As the conversions are quite simple, it would be fine to do the conversions right there in angular. For example:

{{statuses[item.status]}}
{{item.archived.join(',')}}

However, if the data or display requirements are more complex, I would convert the data upon retrieval. This is better practice, and will be able to deal with changes more easily, but will require more code. There are different ways to do this, but ultimately just mean updating the data object prior to assigning it to $scope.


UPDATE

As far as best practices go, it is hard to say for this, because I don't know what other data requirements there are with the project (i.e. is the data ever written back, etc.)

So at this stage, what I would do is simply setup some view functions within your controller. So inside your controller, you might have something like the following:

// usage {{statuses[item.status]}}
$scope.statuses = ['Old Device', 'New Device', 'Activated', 'Unactivated'];

// usage {{displayArchived(item.archives)}}
$scope.displayArchived = function(archives){
    return (archives.length > 0) ? archives.join(',') : 'none';
};

Then you can reference these arrays and functions in your view. If you need to display this information on different views, or if the requirements get more complicated, then I would make a service that returns an object with all the helper functions that you need, which you can inject and assign to $scope whenever you need it.

Matt Way
  • 32,319
  • 10
  • 79
  • 85
0

Make changes in your WebApi to get the results you expect. If Im not wrong, the device status is an enum in server side, which you could send back the text of enum in the api response. And the archived seems to be an array/List which again you could convert to comma seperated string if client needs it that way - string.Join(", ", yourArray);

Thus said, its not necessary that your api should give response exactly how the client expects; sometimes you have to do some extra logic with data in client side to get the work done. But in this case, i would change the api, as giving an integer value as device status doesnt make sense - but if you need that id back in case you have any update, then send an object from api, like {statusId:1, statusName: 'New Device' }. And w.r.t the archived items, thats a trade-off call you gotta make, that change could be done at either side, do the change which would be easier to implement.

Update: As per discussion OP doesnt have control over the api. Adding some code to get started with (plunker - https://plnkr.co/edit/nHLl07I0B33QMdfZoP1N?p=preview):

var app = angular.module("MainModule", []);

app.controller("MainController", function() {

  var self = this;

  self.devices = []; //initially this is empty

  //call your api and get the devices. Im hardcoding for now
  //dummy data
  self.devices = [{
    "DeviceId": "00022B9A000000010001",
    "StagedManifestIdList": [],
    "PendingManifestId": null,
    "PendingTimeStamp": "0001-01-01T00:00:00",
    "ManifestIdList": [
      "00000002",
      "00000001",
      "00000003"
    ],
    "DeviceStatus": 3,
    "Aid": "oAAABTUAAg==",
    "DKiIndex": "DKi00000002",
    "Sha": "R2tiZRQgY/iohXZt5O4HaQwtVe/adWU2VOcKaelJ3Us=",
    "DefaultPayload": "C:\\ProgramData\\\\Payloads\\M4PayloadAuto.xml"
  }, {
    "DeviceId": "00022B9A000000010001",
    "StagedManifestIdList": [],
    "PendingManifestId": null,
    "PendingTimeStamp": "0001-01-01T00:00:00",
    "ManifestIdList": [
      "00000007",
      "00000004",
      "00000003"
    ],
    "DeviceStatus": 1,
    "Aid": "oAAABTUAAg==",
    "DKiIndex": "DKi00000002",
    "Sha": "R2tiZRQgY/iohXZt5O4HaQwtVe/adWU2VOcKaelJ3Us=",
    "DefaultPayload": "C:\\ProgramData\\\\Payloads\\M4PayloadAuto.xml"
  }, {
    "DeviceId": "00022B9A000000010001",
    "StagedManifestIdList": [],
    "PendingManifestId": null,
    "PendingTimeStamp": "0001-01-01T00:00:00",
    "ManifestIdList": [
      "00000004",
      "00000001",
      "00000008"
    ],
    "DeviceStatus": 3,
    "Aid": "oAAABTUAAg==",
    "DKiIndex": "DKi00000002",
    "Sha": "R2tiZRQgY/iohXZt5O4HaQwtVe/adWU2VOcKaelJ3Us=",
    "DefaultPayload": "C:\\ProgramData\\\\Payloads\\M4PayloadAuto.xml"
  }, ]

});

 //add custom filter for display
  app.filter('deviceStatus', function() {

    var deviceStatusLookup = {
      1: "New Device",
      2: "Activated",
      3: "Unactivated"
    };

    return function(statusId) {
      var output = deviceStatusLookup[statusId];
      return output;
    }
  });

HTML:

<!DOCTYPE html>
<html data-ng-app="MainModule">

  <head>
    <script data-require="angular.js@1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body data-ng-controller="MainController as ctrl">


    <table>
      <tr>
        <td><strong>Device Status</strong></td>
        <td><strong>Staged</strong></td>
        <td><strong>Archieved</strong></td>
      </tr>
      <tr data-ng-repeat="device in ctrl.devices">
        <td>{{::device.DeviceStatus | deviceStatus}}</td>
        <td>{{::device.PendingManifestId || 'None'}}</td>
        <td>{{::device.ManifestIdList.join(", ")}}</td>
      </tr>
    </table>     
  </body>
 </html>
Developer
  • 6,240
  • 3
  • 18
  • 24
  • I am not the "owner" of the web api , so that is not going to happen. I just need to massage the data in javascript ... –  Aug 31 '16 at 01:30
  • @CodingAway - thats one-time binding expression; if you dont need two way binding, then this improves a lot of performance. The framework will not keep an eye on the models for change tracking which is rendered using {{::}}. Basically, model watchers will not keep watching these models – Developer Sep 01 '16 at 02:04
  • - I was trying to not be so tightly coupled, but i get app is not defined , http://stackoverflow.com/questions/39282324/angular-app-is-not-defined-when-adding-a-custom-filter-outside-of-function –  Sep 01 '16 at 23:37
  • "app" is not available outside the closure. You shoukd get the module using the name in your controller closure as well; var app=angular.module("module_name"); – Developer Sep 02 '16 at 01:46