Second record from a filtered feature set

641
4
Jump to solution
12-16-2021 09:19 AM
Labels (1)
DamonBreen
New Contributor III

Hi All,

I have a simple test map for trying out a few things. In this map I have a point feature and a related table. The point features will remain static, and each month field users will submit a new record to the related table as an inspection documentation process. I want to reference the current and last records in the pop-up for the parent point features. I already have a solid bit of code that gets the feature set, and filters based on the related fields. I then am using "First" and "OrderBy" to select the most recent related record, and am able to get the pop-up to show the fields I am looking for, but I cannot get the second to last record. I want this to be a rolling pop-up that with each added related record, it references the first and second most recent related records, and pull 2 fields from each record. I assumed "Second" and "OrderBy" would get me what I am after, but "Second" refers to time functions and not what I am after. Can anybody point me in the direction I'm looking for here? Code is inserted below. The parent feature is "Odorizer" and the child table is "Odorizer Inspection" The key field in Odorizer is the GlobalID and the key field in Odorizer Inspection is ODGlobal. I have them ordered by the field "InspectionDate" currently.

 

Thanks,
Damon

var global = $feature.GlobalID; // change the name of the field
var tblReads = FeatureSetByName($map, "Odorizer Inspection");
var sql = "ODGlobal = '" + global + "'"; // if field is text
var relReads = Filter(tblReads, sql);
var cnt = Count(relReads);
Console(cnt);

var result = "";
if (cnt > 0) {
result = "Last Read" + TextFormatting.NewLine;
var currentRead = First(OrderBy(relReads, 'OBJECTID'));
var currentRate = currentRead.CurrentInjectedL / currentRead.MeterReading;
result += "Current Odorant: " + currentRead.CurrentInjectedL + TextFormatting.NewLine;
result += "Current Gas: " + currentRead.MeterReading + TextFormatting.NewLine;
result += "Rate:" + currentRate;
return result;
} else {
result = "There are no reads yet";
}

return result;

  

0 Kudos
1 Solution

Accepted Solutions
jcarlson
MVP Esteemed Contributor

Interesting... Yes, you certainly could, using an array.

 

// as ordered array
var some_arr = []

for (var read in recentTwoReads) {
    var some_value = // insert whatever you need here
    Push(some_arr, some_value)
}

 

After the for loop, the some_arr array will have as many values in it as there were features in the recentTwoReads featureset. These can then be accessed by index, i.e., "some_arr[0]", etc.

If you want to store multiple variables per iteration, you can do that with dicts:

 

// as ordered array of dicts
var some_arr = []

for (var read in recentTwoReads) {
    var some_dict = {
        some_value: // insert whatever you need here
        another_value: // something else
    }
    Push(some_arr, some_dict)
}

 

From that, you can access specific values for each iteration: "some_arr[0]['some_value']".

It can get quite complex if you need it to.

- Josh Carlson
Kendall County GIS

View solution in original post

0 Kudos
4 Replies
jcarlson
MVP Esteemed Contributor

So, you might be able to do this using the Top function, which returns the top X features from a FeatureSet. You could then loop over those features to populate the output string. Try something like this:

var global = $feature.GlobalID; // change the name of the field
var tblReads = FeatureSetByName($map, "Odorizer Inspection");
var sql = "ODGlobal = '" + global + "'"; // if field is text
var relReads = Filter(tblReads, sql);
var cnt = Count(relReads);
Console(cnt);

// Get top two records by objectID
var recentTwoReads = Top(OrderBy(relReads, 'OBJECTID'), 2);

// Empty output string
result = "Recent Readings:";

if (cnt > 0) {

    // Iterate over 2-record featureset
    for (var read in recentTwoReads) {
    
        var RD = read.ReadingDate // I'm assuming you have some field referring to the date of a reading?
        var CO = read.CurrentInjectedL
        var CG = read.MeterReading
        
        result += `\nReading on ${Text(RD, 'DD-MMM-Y')}:\n\tOdorant: ${CO}\n\tGas: ${CG}\n\tRate: ${CO/CG}`
    }
        
    return result;
} else {
    return "There are no reads yet";
}
- Josh Carlson
Kendall County GIS
DamonBreen
New Contributor III

Thanks for the reply. I tweaked some things around and got this to show a pop-up that I thought could work, however in some instances, we may want to take a value from a field in last months inspection and subtract that same value from this month's inspection. Would there be a way with this for loop that I could have it save the field from the 1st iteration into a variable, and then also save the 2nd iteration into a separate variable? I tried to do an internal counter, and log the iterations, but that kind of led me nowhere. If you could think of any way I may be able to save each iteration into their own variables, that would be great.

 

Thanks for the help!

0 Kudos
jcarlson
MVP Esteemed Contributor

Interesting... Yes, you certainly could, using an array.

 

// as ordered array
var some_arr = []

for (var read in recentTwoReads) {
    var some_value = // insert whatever you need here
    Push(some_arr, some_value)
}

 

After the for loop, the some_arr array will have as many values in it as there were features in the recentTwoReads featureset. These can then be accessed by index, i.e., "some_arr[0]", etc.

If you want to store multiple variables per iteration, you can do that with dicts:

 

// as ordered array of dicts
var some_arr = []

for (var read in recentTwoReads) {
    var some_dict = {
        some_value: // insert whatever you need here
        another_value: // something else
    }
    Push(some_arr, some_dict)
}

 

From that, you can access specific values for each iteration: "some_arr[0]['some_value']".

It can get quite complex if you need it to.

- Josh Carlson
Kendall County GIS
0 Kudos
DamonBreen
New Contributor III

Thanks again. I'm working through this array thing, never used one before. I'll have to do some reading on them, but I think I see how it will work. I'm going to go ahead an mark as a solution because I think I see what you are doing here. I really appreciate the help!

0 Kudos