2
\$\begingroup\$

This is working code for input KML files into leaflet map

// Load kml file
fetch('lotA.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)

            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )

      })

fetch('lotB.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)

            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )

      })

fetch('Schematic.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)

            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )

      })

fetch('LotC.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)

            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )

      })

fetch('LotD.kml')
      .then( res => res.text() )
      .then( kmltext => {

            // Create new kml overlay
            parser = new DOMParser();
            kml = parser.parseFromString(kmltext,"text/xml");

            console.log(kml)

            const track = new L.KML(kml)
            map.addLayer(track)

            // Adjust map to show the kml
            const bounds = track.getBounds()
            map.fitBounds( bounds )

      })

Is there a way to write this code shorter? I would like to use it for multiple KML layers.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This code is quite repetitive, and doesn’t adhere to the Don't Repeat Yourself principle.

One way to DRY it out is to abstract the latter promise callback to a separate function:

const addTrackAndBoundsFromKml = kmltext => {

     // Create new kml overlay
     const parser = new DOMParser();
     kml = parser.parseFromString(kmltext,"text/xml");

     const track = new L.KML(kml);
     map.addLayer(track);

     // Adjust map to show the kml
     map.fitBounds( track.getBounds() );

};

Note that const was added before the assignment of parser to avoid a global variable from being created, and bounds was eliminated because it was only used once. Also, semi-colons were added- while they are only required after a handful of statements, it could lead to errors if somehow whitespace got removed. It is a good habit to default to terminating lines with them.

Then use (a reference to) that function whenever it is needed:

// Load kml file
fetch('lotA.kml')
  .then( res => res.text() )
  .then( addTrackAndBoundsFromKml );

fetch('lotB.kml')
  .then( res => res.text() )
  .then( addTrackAndBoundsFromKml );

//etc...

This way if a change needed to happen in that function that parses the KML, adds the track layer and fits the bounds, it could be done in one place instead of each occurrence.

The file names could also be stored in an array and iterated over:

const files = ['lotA.kml', 'lotB.kml', 'Schematic.kml', 'lotC.kml', 'lotD.kml'];
for ( const file of files ) {
    fetch(file)
      .then( res => res.text() )
      .then( addTrackAndBoundsFromKml );
}

It may not be useful but you could consider using Promise.all() though the need to call the asynchronous .text() method on each result might make that really complicated.

You could also consider using the feature async functions with the await operator on the promises, as long as the browser requirements are sufficient.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.