1

I've never created a Javascript module/library before so this is a bit new to me so apologizes for my lack of knowing what to google.

I'm creating a library that will hold information from a URL that is provided by a user. I want to parse the URL's path (the part that comes after the domain) as well as retain a header value that's provided by the URL's response.

It's basic but here's what I have so far:

function Link(someURL) {
  this.url = someURL;
  this.urlPath = "";
  this.uuid = "";

  this.getPath = function (someURL) {
    // do regexp parsing and return everything after the domain
  };

  this.getUUID = function (someURL) {
    // fetch the URL and return what is in the response's "uuid" header
  }
}

Ideally, I'd the module to automatically get all the information upon construction:

var foo = new Link("http://httpbin.org/response-headers?uuid=36d09ff2-4b27-411a-9155-e82210a100c3")
console.log(foo.urlPath);  // should return "uuid"
console.log(foo.uuid);  // should return the contents in the "uuid" header in the response

How do I ensure the this.urlPath and this.uuid properties get initialized along with this.url? Ideally, I'd only fetch the URL once (to prevent rate limiting by the target server).

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
scuba_mike
  • 360
  • 3
  • 12
  • Do you need help in the class, in the library structure or both? – DadiBit Oct 04 '20 at 12:04
  • Instead of exporting a `Link` class or factory directly, you should export a configuration function that lets the user provide all the necessary information. This configuration function will then return a factory for `Link` objects, ensuring that all configuration has been supplied – Aluan Haddad Oct 04 '20 at 13:04
  • 1
    Always try keeping the footprint of the class / constructor implementation and initialization as small as possible. Implement as much as possible of a class' related computation / helper functionality within the module scope but (,if possible,) not directly connected to the class / constructor. Bonus for the `Link` class: make the computation of the necessary url parts lazy (compute when needed first time) but memorizing (save the lazy computed result / one time computation). – Peter Seliger Oct 04 '20 at 13:42
  • @PeterSeliger that's what I'm attempting to do but like I said, I'm very new at this. Once the urlPath and uuid are parsed and retrieved, they don't need to be messed with again but still unsure how to initialize these properties. – scuba_mike Oct 04 '20 at 14:10

1 Answers1

1

After a lot of trial and error, I ended up doing something more like this:

class Link {
  constructor (url_in) {
    const re = RegExp("^https://somedomain.com\/(.*)$");
    this.url = re[0];
    this.linkPath = re[1];
  }

  async getUUID() {
    const res = await fetch("https://fakedomain.com/getUUID?secret=" + this.linkPath);
    this.uuid = res.uuid;
  }

  async getJSON() {
    const res = await fetch("https://fakedomain.com/getJSON?uuid=" + this.uuid);
    this.json = await res.json();
  }

  async initialize() {
    await this.getUUID();
    await this.getJSON();
  }
}


const someLinkData = new Link("https://reallydumbdomain.com/2020/10/4/blog");
someLinkData.initialize()
  .then(function() {
    console.log(this.json); // this now works
  });

I think a future iteration of this will require me to send a promise with the initialize function but for now, this works.

scuba_mike
  • 360
  • 3
  • 12
  • With having landet this approach and already the refactoring in mind, you might, just for your interest, also read ...[*"Are JavaScript ES6 Classes of any use with asynchronous code bases?"*](https://stackoverflow.com/questions/37556058/are-javascript-es6-classes-of-any-use-with-asynchronous-code-bases). – Peter Seliger Oct 05 '20 at 02:00