0

I'm trying to capture the client-side IP address and automatically store it as the value inside of an input field. Here's my code so far:

var Ip;
fetch('https://api.ipify.org/?format=json')
  .then(res => res.json())
  .then(data => Ip = data.ip)
  .then(() => console.log(Ip))
  .then(() => document.getElementById('awf_field-106493013').value = Ip);

This is returning the error:

Uncaught (in promise) TypeError: Cannot set property 'value' of null

.value is the bit of code it doesn't like, which seems to mean awf_field-106493013 is null, but I know for a fact by the time this function has been called the input has populated, and I'm positive this is the correct input id.

What am I missing?

EDIT Here's what the input looks like:

<label class="previewLabel" for="awf_field-106493013">ipaddress:</label>
<div class="af-textWrap"><input type="text" id="awf_field-106493013" class="text" name="custom ipaddress" value=""  onfocus=" if (this.value == '') { this.value = ''; }" onblur="if (this.value == '') { this.value='';} " tabindex="503" /></div>

This is all called before the javascript code so it should be there.

Edit 2 Here's all the javascript I currently have on my page, I just made it so when the document is ready, then the fetch is made:

<script type="text/javascript">
function getUrlParam(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
      results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

var tid = getUrlParam("adid");
var date = Date(Date.now());

jQuery(document).ready(function () {
  setIp();

  jQuery('#awf_field-106493014').val(date.toString()); //Time
  if (tid != null) {
    jQuery('#awf_field-106493015').val(tid.toString()); //Tid
  } else {
    jQuery('#awf_field-106493015').val("nulltid"); //Tid
  }
});

function setIp(){
  var Ip;
  fetch('https://api.ipify.org/?format=json')
    .then(res => res.json())
    .then(data => Ip = data.ip)
    .then(() => console.log(Ip))
    .then(() => document.getElementById('awf_field-106493013').value = Ip);
}
</script>

Returns the same

19
  • You can check if that element is loaded or not and then call your fetch request. Commented Apr 28, 2020 at 22:14
  • 1
    Haven't you tested yet whether getElementById returns a non-null value? Commented Apr 28, 2020 at 22:15
  • I suspect the argument chaining is incomplete: .then(res => res.json()).then(data => data.ip).then(ip => { console.log(ip); return ip; }).then(ip => document.getElementById('awf_field-106493013').value = ip); should fix it. Commented Apr 28, 2020 at 22:18
  • Seems to me like there is no element with id="awf_field-106493013". "Return value: An Element object describing the DOM element object matching the specified ID, or null if no matching element was found in the document." - Document.getElementById() documentation Commented Apr 28, 2020 at 22:19
  • Works fine, provided the element ID is correct. jsfiddle.net/4tphdur9 Commented Apr 28, 2020 at 22:20

3 Answers 3

1

The code from the question works with me - run the snippet. The last JS line uses an alternative selector for the target input field, but the original line (commented out here) works just as fine.

function getUrlParam(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
      results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

var tid = getUrlParam("adid");
var date = Date(Date.now());

jQuery(document).ready(function () {
  setIp();

  jQuery('#awf_field-106493014').val(date.toString()); //Time
  if (tid != null) {
    jQuery('#awf_field-106493015').val(tid.toString()); //Tid
  } else {
    jQuery('#awf_field-106493015').val("nulltid"); //Tid
  }
});

function setIp(){
  var Ip;
  fetch('https://api.ipify.org/?format=json')
    .then(res => res.json())
    .then(data => Ip = data.ip)
    .then(() => console.log(Ip))
    .then(() => document.querySelector('*[name="custom ipaddress"]').value = Ip);
// was:        .then(() => document.getElementById('awf_field-106493013').value = Ip);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="previewLabel" for="awf_field-106493013">ipaddress:</label>
<div class="af-textWrap"><input type="text" id="awf_field-106493013" class="text" name="custom ipaddress" value=""  onfocus=" if (this.value == '') { this.value = ''; }" onblur="if (this.value == '') { this.value='';} " tabindex="503" /></div>

Remark

This is not a genuine answer. It serves to sort out the OP's issue and will be modified or deleted thereafter

Sign up to request clarification or add additional context in comments.

2 Comments

unfortunately I am not able to modify the name of the input field as it was generated by Aweber
You don't have to. In your original code you referenced the input element by its id. The name attribute should be unique as well - check that. You have the power of CSS selectors at your disposition to uniquely identify an element in the DOM. If you use positional information only, you do not even have to resort to attributes at all ( This is not an advisable solution, though ).
1

The issue was solved by modifying https://api.ipify.org/?format=json, which returns abck some sort of weird json object to https://api.ipify.org/ which, as per their documentation, returns back a standard text reply.

Comments

0

the url you used to fetch ip didn't work on my machine, changed API provider and now it works fine.

<label class="previewLabel" for="awf_field-106493013">ipaddress:</label>
<div class="af-textWrap">
    <input type="text" id="awf_field-106493013" class="text" name="custom ipaddress" value=""  onfocus=" if (this.value == '') { this.value = ''; }" onblur="if (this.value == '') { this.value='';} " tabindex="503" />
</div>
<script>
var Ip;
fetch('http://ip-api.com/json/?fields=status,query')
  .then(res => res.json())
  .then(data => Ip = data.query)
  .then(() => console.log(Ip))
  .then(() => document.getElementById('awf_field-106493013').value = Ip);
</script>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.