0

is there a way to catch all fields that have not been set in a class ? i am parsing a json file and sometimes field names change and i would like to know which fields have not been set to make it simpler to fix. Below is a sample of my code i use to sett the fields in class. This is only small sample , my class has over 250 fields so checking one by one is not going to work.

const myLand = new mls.Land();
    myLand.landLease = trimString(data["LAND LEASE?"]);
    myLand.commonInterest = trimString(data["COMMON INTEREST"]);
    myLand.landLeaseAmount = trimString(data["LAND LEASE AMOUNT"]);
    myLand.landLeaseAmtFreq = trimString(data["LAND LEASE AMT FREQ"]);
    myLand.landLeasePurch = trimString(data["LAND LEASE PURCH?"]);
    myLand.landLeaseRenew = trimString(data["LAND LEASE RENEW"]);

newListing.land = myLand;

and here is the Trim function

function trimString(inputStr: string) {
    return (inputStr !== undefined && typeof inputStr === "string") ? inputStr.trim() : undefined;
  }
MisterniceGuy
  • 1,646
  • 2
  • 18
  • 41
  • Could you add what you want as output/outcome? And how your question relates to assignment to another object? Isn't that irrelevant to your question? – trincot Apr 13 '19 at 17:15
  • You mean you want to check which fields are `undefined`? – Dennis Vash Apr 13 '19 at 17:15
  • What the ultimate goal is to get a list of all fields in a class which have not been set or undefined – MisterniceGuy Apr 13 '19 at 17:18
  • Use a model library that lets you create a schema to validate your input as well as do input transformations and key mappings so you can simply pass in your whole `data` object into the class instance – charlietfl Apr 13 '19 at 17:19

3 Answers3

2

Using Object.entries(), filter by value and map by key.

const objWithUndefinedValues = {
  a: undefined,
  b: 2,
  c: "3"
}

const undefinedKeys = Object.entries(objWithUndefinedValues)
  .filter(([, value]) => value === undefined)
  .map(([key, ]) => key)

console.log(undefinedKeys);
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
1

If you need to check whose keys of the object representing your class have been set to undefined, you can use Object.keys() and Array.filter() like this:

function trimString(inputStr)
{
    return (inputStr !== undefined && typeof inputStr === "string") ? inputStr.trim() : undefined;
}

const myLand = {};
myLand.landLease = trimString("123");
myLand.commonInterest = trimString(" common interest ");
myLand.landLeaseAmount = trimString(null);
myLand.landLeaseAmtFreq = trimString({});

let undefinedKeys = Object.keys(myLand).filter(k => myLand[k] === undefined);

console.log("Undefined fields:", undefinedKeys);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Shidersz
  • 16,846
  • 2
  • 23
  • 48
  • Tried your code but my TSC compiler does not like it and complains about src/helper/mlslisting.ts:233:65 - error TS7017: Element implicitly has an 'any' type because type 'mls.Land' has no index signature. 233 const undefinedKeys = Object.keys(myLand).filter((k) => myLand[k] === undefined); – MisterniceGuy Apr 13 '19 at 17:55
  • @MisterniceGuy Take this as an example of how to approach, I haven't worked with `typescript` so i'm not sure what the error means. Maybe next link can help you: https://stackoverflow.com/questions/32968332/how-do-i-prevent-the-error-index-signature-of-object-type-implicitly-has-an-an – Shidersz Apr 13 '19 at 19:29
0

You could just create an array of expected fields, and then filter those:

const expectedFields = ["LAND LEASE?", "COMMON INTEREST", "LAND LEASE AMOUNT", "LAND LEASE AMT FREQ", "LAND LEASE PURCH?", "LAND LEASE RENEW"];

const absentFields = expectedFields.filter(field => !(field in data));

If you want to also capture fields which are not of type string:

const absentFields = expectedFields.filter(field => typeof data[field] !== "string");

Your routine for assigning the data, could also be put in a loop:

const camelCase = field => field.match(/\w+/g).map((word, i) => (i ? word[0] : "") + word.slice(+!!i).toLowerCase()).join``;

const expectedFields = ["LAND LEASE?", "COMMON INTEREST", "LAND LEASE AMOUNT", "LAND LEASE AMT FREQ", "LAND LEASE PURCH?", "LAND LEASE RENEW"];

// Sample data
const data = { "LAND LEASE?": "a", "LAND LEASE AMOUNT": "n" }

const myLand = {};
for (const field of expectedFields) {
    const value = data[field];
    if (typeof value === "string") myLand[camelCase(field)] = value.trim();
}

console.log(myLand);
console.log("missing:", expectedFields.filter(field => typeof data[field] !== "string"));
trincot
  • 317,000
  • 35
  • 244
  • 286