user6571640
user6571640

Reputation: 117

How to use chained prototype for a string

I want to use chained prototype for a string. But one I return string prototype is no more applied. How to fix that without returning this by prototype method, same as native String.prototype.

function StringUtil(str){
  this.str = str;
}

StringUtil.prototype.toCamelCase = function () {
  return this.str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) {
    return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
  }).replace(/\s+/g, '');
};

StringUtil.prototype.toSlug = function() {
  return this.str.toString().toLowerCase()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
    .replace(/^-+/, '')             // Trim - from start of text
    .replace(/-+$/, '');            // Trim - from end of text
};

var util = new StringUtil('this is a custom string');
console.log(util.toCamelCase()) // thisIsACustomString
console.log(util.toSlug()) // this-is-a-custom-string

util.toCamelCase().toSlug() // This does not work

Upvotes: 2

Views: 66

Answers (3)

gurvinder372
gurvinder372

Reputation: 68393

You need to return this from your methods for chaining to work.

For example

function StringUtil(str){
  this.str = str;
}

StringUtil.prototype.toCamelCase = function () {
  this.str = this.str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) {
    return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
  }).replace(/\s+/g, '');
  return this;
};

StringUtil.prototype.toSlug = function() {
  this.str = this.str.toString().toLowerCase()
    .replace(/\s+/g, '-')           // Replace spaces with -
    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
    .replace(/^-+/, '')             // Trim - from start of text
    .replace(/-+$/, '');            // Trim - from end of text
   return this;
};


StringUtil.prototype.setStr =function(str) {
   this.str = str;
   return this;
};

StringUtil.prototype.toString =function() {
   return this.str.toString();
};


var util = new StringUtil('this is a custom string');
console.log(util.toCamelCase().toString()) 
console.log(util.setStr("this is a custom string").toSlug().toString()) 

console.log(util.toCamelCase().toSlug().toString())

I have added a couple of methods to your class to explain the effect of chaining.

  • toString() - Since you are returning this, console.log won't print the data in required format.
  • setStr() - So, that you can see toSlug working on original string.

Upvotes: 1

ianaya89
ianaya89

Reputation: 4233

The problem is that you are returning a String object inside your StringUtil methods (replace returns a new string). So string prototype doesn't have the new methods that you are creating. You can fix it returning a new StringUtil object in your new methods:

function StringUtil(str){
  this.str = str;
}

StringUtil.prototype.toCamelCase = function () {
  return new StringUtil(this.str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) {
    return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
  }).replace(/\s+/g, ''));
};

Upvotes: 1

passion
passion

Reputation: 1360

StringUtil.prototype.toCamelCase = function () {
  return this.str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(letter, index) {
    return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
  }).replace(/\s+/g, '');
};

You are returning the value returned by this.str.replace same with String.prototype.replace'return (a string) .

Same with your next function .

Upvotes: 1

Related Questions