1

I'm trying to make a function that -

Grabs all the links on a page, Compares those links with a link that the user inputs, and Checks if the link already exists on the page

It seems like I can get the value from the input box, and have converted the links into an array. However, even though I match the values (E.g. http://www.test.com/), the .includes function keeps returning false.

I've tried converting the array to a string. That worked, but it compared everything, and not the specific links. (E.g. Even if I just put "h" into the input box, it would say there's a duplicate link.)

<!DOCTYPE html>
    <html>
    <head>

    </head>
<body>


URL: <input id="URL" type="text" name="URL"><br>
<input onClick="grabLinks()" type="submit" value="Submit">
<div id="dupliURLNum">0</div>

<script>

function grabLinks() {

    //Get URL from input
    var URL = document.getElementById('URL').value;

    //Get all links
    var links = document.querySelectorAll('a');

    //Convert Nodelist to Array
    var linksArr = Array.from(links);


    //Compare Link to Array
    var compareArr = linksArr.includes(URL);


    alert(URL);
    alert(linksArr);
    alert(compareArr);    

        if (compareArr === true) {
            alert('Duplicate');
        }
        else {
            alert('NoDuplicate');
        }

};

</script>

<a href="http://www.test.com">test</a>
<a href="https://stackoverflow.com">stackoverflow</a>
<a href="https://www.ford.com">ford</a>

</body>
</html> 

The expected result would be a user types "http://www.test.com" into the input box. Then compareArr would return true.

If they type in a link that isn't on the page, compareArr would return false.

The actual result is that it always returns false.

I've added alerts just for debugging purposes.

2
  • You sure var linksArr = Array.from(links) converts all the a elements to URLs ready for comparison? Commented Aug 25, 2019 at 18:58
  • A HTMLLinkElement is not a string! They can never be === (that's the comparison that Array#includes does). Better do linksArr.some(a => a.href === URL); Commented Aug 25, 2019 at 19:18

7 Answers 7

2

The reason why it's failing is because, Array.from(document.querySelectorAll('a')) will give you a array of nodeLists but it does not give you a link!

You would need to extract the href values and then compare in order to achieve what you're looking for!

EDIT: I've made few basic changes to your code and you can verify that it works!

<!DOCTYPE html>
    <html>
    <head>

    </head>
<body>


URL: <input id="URL" type="text" name="URL"><br>
<input onClick="grabLinks()" type="submit" value="Submit">
<div id="dupliURLNum">0</div>

<script>

function grabLinks() {

    //Get URL from input
    var URL = document.getElementById('URL').value;

    //Get all links
    var links = document.querySelectorAll('a');

    //Convert Nodelist to Array
    var linksArr = Array.from(links);
  
    //Compare Link to Array
    const res = linksArr.filter(link => link.href.includes(URL));


        if (res.length) {
            alert('Duplicate');
        }
        else {
            alert('NoDuplicate');
        }

};

</script>

<a href="http://www.test.com">test</a>
<a href="https://stackoverflow.com">stackoverflow</a>
<a href="https://www.ford.com">ford</a>

</body>
</html> 

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

Comments

0

You need to get the href from the each node from the NodeList object, links.

Iterate over the links using forEach and create an array of hrefs.

The solution below works fine.

<!DOCTYPE html>
    <html>
    <head>

    </head>
<body>


URL: <input id="URL" type="text" name="URL"><br>
<input onClick="grabLinks()" type="submit" value="Submit">
<div id="dupliURLNum">0</div>

<script>

function grabLinks() {

    //Get URL from input
    var URL = document.getElementById('URL').value;

    //Get all links
    var links = document.querySelectorAll('a');
    //Convert Nodelist to Array
    var linksArr = [];
    links.forEach(node => linksArr.push(node.href))


    //Compare Link to Array
    var compareArr = linksArr.includes(URL);


    alert(URL);
    alert(linksArr);
    alert(compareArr);    

        if (compareArr === true) {
            alert('Duplicate');
        }
        else {
            alert('NoDuplicate');
        }

};

</script>

<a href="http://www.test.com">test</a>
<a href="https://stackoverflow.com">stackoverflow</a>
<a href="https://www.ford.com">ford</a>

</body>
</html>

3 Comments

Perfect! I knew I must not have been getting the hrefs correctly. I also added var compareArr = linksArr.includes(URL + "/"); from Abitos post to take care of the trailing /. Thanks everyone!
@timothybeachboard Glad to help, if this answer solved your problem please mark it as accepted by clicking the check mark next to the answer. see: How does accepting an answer work? for more information.
And thank you again! It's my first time posting. =)
0

You need to loop trough that array in order to make comparation with each element into array

2 Comments

That's what Array.prototype.includes does.
No, it's not. Array.includes will only verify if the direct value is present in the array. In this case, it's not!
0

linksArr is actually still an array of objects. Use Map to grab the piece of the object you want. In this case, probably href.

Updated code:

//Convert Nodelist to array of objects
var linksArr = Array.from(links);

// Convert object array to string array
var newLinksArr = linksArr.map(nodeObject => nodeObject.href)

console.log(newLinksArr)
// ['http://www.test.com', 'https://stackoverflow.com', 'https://www.ford.com']

Comments

0

Your linksArr is an array of HTMLAnchorElements which you are comparing against a String. They are different types, so they will never match. You can use Array.prototype.find() to find the first matching element in the array or alternatively Array.prototype.some() if you just want to know if it exist in the list.

function grabLinks() {

  var url = document.getElementById('URL').value;

  var links = document.querySelectorAll('a');

  //Convert Nodelist to Array
  var linksArr = Array.from(links);

  //Compare Link to Array
  var compareArr = linksArr.some(a => a.href === url);
  
  if (compareArr === true) {
    console.log('Duplicate');
  } else {
    console.log('NoDuplicate');
  }

};
URL: <input id="URL" type="text" name="URL"><br>
<input onClick="grabLinks()" type="submit" value="Submit">
<div id="dupliURLNum">0</div>

<a href="http://www.test.com">test</a>
<a href="https://stackoverflow.com">stackoverflow</a>
<a href="https://www.ford.com">ford</a>

Please do keep in mind that the href is not always the exact string you enter in the href attribute. It "Is a USVString that reflects the href HTML attribute, containing a valid URL of a linked resource.". In this case you need to search for the URL https://stackoverflow.com/. Without the slash, it wont find it.

Comments

0

When you are getting all the links using

var links = document.querySelectorAll('a');

You are getting HTMLElements objects in links.

So during converting to array you can extract links from those HTMLElement objects

var linksArr = Array.from(links).map(link => link.href);

Also links in linksArr will have a trailing "/". So in compareArr use

var compareArr = linksArr.includes(URL + "/");

Or you could remove this trailing "/" from all the links in linksArr

Comments

0

Whenever you use .includes() then make sure your array in the form of this

const array = [1, 2, 3];
console.log(array.includes(1); // true

On above case you will got true.

If your array in the form of objects like this

const array = [{ id:1 }, { id:2 }];
console.log(array.includes(1); // false

Then .includes() doesn't work and always gives you false. So make sure in which array format you have and apply proper method on it based on your requirement.

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.