-3

in the below posted code i would like to loop through the contents of the array

features[0]["values_"]["geometry"]["flatCoordinates"]

for all the console statements that are outside the for-loop, they gets printed and they contain data.however, when i run the App, i receive the following error

ERROR TypeError: Cannot set property '0' of undefined

to solve this issue i commented out the first two lines inside the for-loop, and the values of the variable 'i' gets printed. only when i acrivate the first two lines inside the loop the error message is received. please let me know how to fix this error

code:

private renderSelectedSite(){
    var features = (new GeoJSON()).readFeatures(this.selectedSite.geometry);
    console.log("this.selectedSite.geometry: ",this.selectedSite.geometry)
    console.log("features ",features)
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"])
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"].length)//84
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"][0])//736437.816446109
    var points: any[];
    for (var i = 0; i < features[0]["values_"]["geometry"]["flatCoordinates"].length; i++) {
        var e = features[0]["values_"]["geometry"]["flatCoordinates"][i];
        points[i] = transform(e,'EPSG:4326','EPSG:3857');
        console.log("points[i] ",i)
    }
Amrmsmb
  • 1
  • 27
  • 104
  • 226
  • Could you adjust the code in your question to be a working snippet that we can work with and modify in our answers? – Brandon McConnell Apr 16 '21 at 09:50
  • Adding also the coordinates you are trying is usually very very useful (as you see in this site, order of coordinates changes on some datum, some uses angles, and some uses meters (or other length units), etc.) – Giacomo Catenazzi Apr 16 '21 at 12:21

1 Answers1

3

You need to initialize the variable points.

var points: any[] = [];

Here are some QOL improvements I'd suggest:

  1. Use const/let instead of var. See here for the canonical difference.
  2. Use Array#map instead of for.
private renderSelectedSite(){
  const features = (new GeoJSON()).readFeatures(this.selectedSite.geometry);
  let points: any[] = features[0]["values_"]["geometry"]["flatCoordinates"].map(e => 
    transform(e,'EPSG:4326','EPSG:3857')
  );
}
  1. As @Cerbrus mentioned in the comment, I'd also help with type checking to define a type for the object (eg. using a TS interface) and use dot access instead of using bracket notation to access the properties.

Update: logging inside Array#map

Enclose the callback in curly braces and explicitly return the response if you have more than one statement.

let points: any[] = features[0]["values_"]["geometry"]["flatCoordinates"].map(e => {
  console.log(transform(e,'EPSG:4326','EPSG:3857'));
  return transform(e,'EPSG:4326','EPSG:3857');
});

console.log(points);

Update: Duplicate questions

Hopefully this solves the issue from here and here too. Please stop posting duplicate questions for the same issue.


If you're sure the flat co-ordinates will always only contain 8 entries, you could construct the arranged co-ordinates without any fuss.

const flatCoords = features[0]["values_"]["geometry"]["flatCoordinates"];
const coords = [
  [flatCoords[0], flatCoords[1]],
  [flatCoords[2], flatCoords[3]],
  [flatCoords[4], flatCoords[5]],
  [flatCoords[6], flatCoords[7]],
];

Then you could iterate the array and fetch the points using Array#map.

let points = coords.map(coord => transform(coord,'EPSG:4326','EPSG:3857'));

Update: dynamic number of flat co-ordinates

You could write a quick routine to convert the flat-coords to the desired format

toCoords(flatCoords: any) {
  let coords = [];
  for (let i = 0; i < flatCoords.length; i += 2) {
    coords.push([flatCoords[i], flatCoords[i+1]])
  }
  return coords;
}
const coords = this.toCoords(features[0]["values_"]["geometry"]["flatCoordinates"];
let points = coords.map(coord => transform(coord,'EPSG:4326','EPSG:3857'));
ruth
  • 29,535
  • 4
  • 30
  • 57
  • Use dot access instead of brackets: `features[0].values_.geometry.flatCoordinates` – Cerbrus Apr 16 '21 at 09:55
  • @Cerbrus: Good point, but without a proper type to guide, the TS linter might just throw something like "cannot find property" errors. I'll add it to the post. – ruth Apr 16 '21 at 09:56
  • TS applies the same rules to both types of access. If it works in brackets, it will work in dot notation. So, either `features` is strongly typed here and TS knows what properties work, or it's `any`. – Cerbrus Apr 16 '21 at 10:00
  • would you please tell me why when i print the content of the transformation i receive undefined??console.log(transform(e,'EPSG:4326','EPSG:3857')) returns undefined – Amrmsmb Apr 16 '21 at 10:03
  • Are you logging _in_ the `.map` callback? Or have you taken that line out of the context? Note how that `.map` has an argument, `e`... – Cerbrus Apr 16 '21 at 10:06
  • @Cerbrus: Yes TS would compile nevertheless. I meant TS linter might throw an error. Few examples: [1](https://stackoverflow.com/questions/63575749/angular-observable-for-pdfjs-metadata-extraction/63576285#comment112430341_63576285), [2](https://stackoverflow.com/questions/61510211/im-trying-to-get-key-value-pairs-from-json-data-via-an-external-api-and-display/61510340#comment108813090_61510340), [3](https://stackoverflow.com/questions/61448660/argument-of-type-object-is-not-assignable-to-parameter-of-type-string-ioni/61448860#comment108700951_61448860),.. – ruth Apr 16 '21 at 10:06
  • Then you're making a lot of assumptions about the user's lint configuration... This assumes the linter doesn't accept `any`, which isn't default... – Cerbrus Apr 16 '21 at 10:09
  • @amrmbso01: You need to provide more context on where and how you've attempted it. Nevertheless I've updated the answer. – ruth Apr 16 '21 at 10:09
  • @Cerbrus: I agree, my assumption is based on experiences with multiple questions coming up with the same error when the answer was provided with the dot notation. – ruth Apr 16 '21 at 10:12
  • @MichaelD thanks, flatcoordinates does not always contains 8 but it contains always even number of entries.would you please modify your code to accommodate this case – Amrmsmb Apr 16 '21 at 11:27
  • @MichaelD i will study and inform once tested.regards – Amrmsmb Apr 16 '21 at 11:39
  • @amrmbso01: I'm not exactly sure of the reason for the downvotes. In my view, the standalone question is fine. – ruth Apr 16 '21 at 11:48
  • If you are using `flatCoordinates` the answer is correct, but why use internal properties which are not part of the API when the API method `features[0].getGeometry().getCoordinates()` will return coordinate pairs? – Mike Apr 16 '21 at 12:09