0

I'm having a problem with my javascript code.

It basically consists of a script that accesses the exif of a photo and then shows it on an HTML page, more specifically the latitude and longitude of it.

The idea is to then use both the latitude and longitude on a Google maps iframe to then show the location that photo was taken. But that's later as this is only a test page I'm using to ecperiment the workings of it.

The thing is that before using the latitude and longitude, it has to be converted into a format recognised by that same iframe:

EX: the output of "latitude = EXIF.getTag(this, "GPSLatitude")" would be:

41,23.0692,0

and it needs to be something like this:

41.38448666666667

I have a function that does just that and it works if i do something like this:

var toDecimal = function (number) {
  var d = Math.floor(number[0]);
  var m = Math.floor(number[1]);
  var s = ((number[1]%1)*60);

  var dms = d+(m/60)+(s/3600);

  return dms

};

var latitude_teste="41,23.0692,0";
var latitude_array = latitude_teste.split(',');
var latitude_final = toDecimal(latitude_array);
var local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;

But if I try to use this method above like this (latitude being the variable from the function getExif()):

var latitude_teste=latitude;
var latitude_array = latitude_teste.split(',');
var latitude_final = toDecimal(latitude_array);
var local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;

It won't show any value at all for latitude...

Why am I having this problem? Is it some syntax mistake?

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
    <style>
        img{
            width: 500px;
            max-height: auto;
        }   
    </style>    
</head>

<body>

    <img src="https://c1.staticflickr.com/5/4867/30883801817_bf122bc498_o.jpg" id="img1" />


    <h1>Latitude Exif</h1>
    <p id="local_lat"></p>

    <h1>Longitude Exif</h1>
    <p id="local_lon"></p>

    <h1>Latitude Final</h1>
    <p id="local_lat_final"></p>

    <h1>Longitude Final</h1>
    <p id="local_lon_final"></p>

    <script src="exif.js"></script>

    <script>

        window.onload=getExif;


        function getExif() {
            var img1 = document.getElementById("img1");
            EXIF.getData(img1, function() {

            latitude = EXIF.getTag(this, "GPSLatitude");
            var longitude = EXIF.getTag(this, "GPSLongitude");  

            var local_lat = document.getElementById("local_lat");
            var local_lon = document.getElementById("local_lon");

            local_lat.innerHTML = `${latitude}`;
            local_lon.innerHTML = `${longitude}`;
            });


        }

        /*função para converter latitude e longitude do exif.js 
        em graus decimais, legíveis pelo google maps*/

        var toDecimal = function (number) {


            var d = Math.floor(number[0]);
            var m = Math.floor(number[1]);
            var s = ((number[1]%1)*60);

            var dms= d+(m/60)+(s/3600);

            return dms

        };

        var latitude_teste="41,23.0692,0";
        var latitude_array = latitude_teste.split(',');
        var latitude_final = toDecimal(latitude_array);
        var local_lat_final = document.getElementById("local_lat_final");
        local_lat_final.innerHTML = `${latitude_final}`;

        /*THIS PIECE OF CODE BELOW WON'T WORK if used to replace the one above*/


        /*
        var latitude_teste=latitude;
        var latitude_array = latitude_teste.split(',');
        var latitude_final = toDecimal(latitude_array);
        var local_lat_final = document.getElementById("local_lat_final");
        local_lat_final.innerHTML = `${latitude_final}`;

        */

        var longitude_teste="2,6.4013,0";
        var longitude_array = longitude_teste.split(',');
        var longitude_final = toDecimal(longitude_array);
        var local_lon_final = document.getElementById("local_lon_final");
        local_lon_final.innerHTML = `${longitude_final}`;


    </script>

</body>
</html>
Rafael Lopes
  • 63
  • 1
  • 8
  • 1
    The problem is most likely *timing*. ***When*** does `latitude` become available…? – deceze Dec 28 '18 at 11:37
  • Supposedly on window.onload=getExif; – Rafael Lopes Dec 28 '18 at 11:41
  • Exactly, `getExif` will be executed *sometime later* (on window load), yet your code expects the variable to be there immediately. Further, even `EXIF.getData` may be executing asynchronously. – deceze Dec 28 '18 at 11:43
  • What should I do then? (adding to some needed reading I guess). Is there a way to implement some kind of delay for the code to only expect the variable after it has become available? – Rafael Lopes Dec 28 '18 at 11:46
  • @deceze while your diagnostic is correct (timing issue), I wouldn't close this as a dup of 14220321 - the solution here is quite simply to move the top-level code (the "non working" part) whithin `getExif()` so it's executed at the right time, no need to bother with async/await etc and we ALREADY have the "callback" (getExif, to name it). – bruno desthuilliers Dec 28 '18 at 11:49
  • @bruno Well that is also widely discussed there, probably most succinctly in https://stackoverflow.com/a/23819901/476. – deceze Dec 28 '18 at 11:57
  • @RafaelLopes just move your "code that doesn't work" within the callback you pass to `EXIF.getData` (and remove the code used to parse 'latitude' and 'longitude', thos are already arrays), cf https://gist.github.com/BrunoDesthuilliers/de5ee721437d50513d11493c85d07957 – bruno desthuilliers Dec 28 '18 at 12:00
  • @brunodesthuilliers Done that and it is indeed working now! Thanks very much! – Rafael Lopes Dec 28 '18 at 12:02
  • @RafaelLopes do you now understand why it didn't work and why/how my gist solved the problem ? (If not, take time to understand it, else you will get similar problems again and again and again). – bruno desthuilliers Dec 28 '18 at 12:07
  • @brunodesthuilliers I did understand the sense of it being a question of timing between when the values are available and when they are requested. The technical part of it will require time to refine as I'm doing this project a bit on a "self-learning" way. This kind of experience with errors/mistakes is with no doubt, enriching to my knowledge. This bit of code is also only a test as I'll need to convert it to work, not with an image already loaded on the website but with an image the user selects using – Rafael Lopes Dec 28 '18 at 12:11
  • @RafaelLopes, you should not update your question with code you get from solutions. It makes it very confusing. StackOverflow is intended to have answers in the answer section, not in the question area. – trincot Dec 28 '18 at 12:35
  • @trincot fixed :) – Rafael Lopes Dec 28 '18 at 16:59

1 Answers1

1

The latitude you get from EXIF.getTag() is already an array. It is only because you output it as a string that you see a comma-separated string, but it really is an array.

So in your code you shouldn't do the split():

var latitude_teste=latitude;
var latitude_array = latitude_teste.split(',');
var latitude_final = toDecimal(latitude_array);

Instead just do:

var latitude_final = toDecimal(latitude);

Addendum: you should place this code in the callback you have to EXIF.getTag(). That you tried to access the latitude and longitude outside of it is the reason for the duplicate/closure.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • I tried this and it still won't show any value on the page... weird. Also, if I use "typeof" for latitude it does indeed say it is a string. – Rafael Lopes Dec 28 '18 at 11:34
  • @trincot your observation is technically correct (and the code will not work without this fix), but that's not the root cause either - the first problem is that this code should be within the `EXIF.getData`'s callback. – bruno desthuilliers Dec 28 '18 at 12:05
  • @brunodesthuilliers, as far as I can see in the code the OP has posted at the end of his question, the code *is* correctly put within the callback, albeit his code is not indented properly. – trincot Dec 28 '18 at 12:26
  • @trincot this code is the fixed version I posted as a gist, not the original non-working code ;-) – bruno desthuilliers Dec 28 '18 at 12:30
  • Oh I see, the OP has incrementally updated their question which now even includes this fix. My, my, this is confusing :-) – trincot Dec 28 '18 at 12:33
  • @trincot I'm sorry for the confusion created by my last edit. Was not intentional and it's fixed now :) – Rafael Lopes Dec 28 '18 at 17:00