Node.js REST, Mongo tips

  • In express library functions: post(), get() will stop the execution of code if you write return. It’s like in any other function in programming. keyword return will always stop the function execution.
  • When you write (res is the response callback function) res.end(), res.json(), res.send(), in other words when you end the response you cannot utilize res callback again it becomes irrelevant since you completed your restful service with a response. If you have any code after res.something() it will execute till you specify a return but res will not be available anymore. If you use it however, it will throw an error.
    Refer: Execute code after res.end() (StackOverflow)
  • You don’t need to return res.end(), json(), send() if you don’t have code which needs to execute after it.
  • If you don’t have anything to send to the Frontend side then use res.end() to complete the service action.
  • Use next function, specified at the end of restful service callback function:
    .get((req, res, next) => {action}

    to catch errors and forward them to the middleware:

    if (err) {
        return next(err);
    }

    the return next() will go to the already built in error handler and will result with a 500 XHR failed request on the Frontend. Also applies for catch() blocks, having next(err) will also result with Node.js built in error handler execution giving 500.

  • A Node.js mongoose query is not a JS Promise. They just represent a async operation which returns a then so that you can apply: query().then(res=>console.log(res));
    Refer: Mongoose async queries (StackOverflow)
    If you want a real instance of JavaScript Promise then put an exec() after your “fake” Mongoose query promise: query().exec().then(res=>console.log(res));
  • The default status for res.send(), res.json() is 200 thereby no need for res.status(200).send() or res.status(200).json();
  • In Mongoose findOneAndUpdate query
    User.findOneAndUpdate(findQuery, updateData, {
       upsert:true,
       useFindAndModify:false,
       new:true
    })
    upsert:true represents that if the record doesn’t exist a new one will be created/inserted
    useFindAndModify:false removes deprecation warning
    new:true gives the response of updated data, otherwise you get the data of the current findQuery record.
    I like to specify those parameters for each query so that I know what to expect from it.
  • ObjectId(userId) vs
    new ObjectId(userId) are the same, use whichever one you like but be consistent once you pick one.
  • Do not close your mongo database connection after terminating your query and then reopen upon querying database. You should have/define a pool of connections instead and closing it in Node.js process termination
    process.on(‘SIGINT’, mongo.mongoDisconnect).on(‘SIGTERM’, mongo.mongoDisconnect);
    Refer: Closing a Mongo connection (StackOverflow)
  • Do not use query.remove() for deleting data from the database it’s obsolete, use deleteOne, deleteMany instead.
  • For clearing the session and destroying the browser cookie use:
    req.sessionOptions.maxAge = 0;
    req.session=null;
    res.clearCookie(‘cookieName’);
    res.end(); 
    (I use it to logout the user)

Angular 2 Jasmine unit testing (quick overview)

KEYWORDS:

  • describe: optional, describe the entire unit testing class
  • it: must include it when writing isolated unit test
  • async: tell the test framework to wait until the return promise or observable is completed before treating the test as completed. when all async operations are completed the next test (if exists) is able to start executing
  • beforeEach: for creating new instances for another test to start from the beginning
  • TestBed: creates components instance, configure module, simulate module
  • Access field/variable: fixture.componentInstance.some_variable_name OR if already instantiated then component.some_variable_name
  • detectChanges: only triggered when an property change occurs inside a .ts file
  • configureTestingModule: configures a “fake” module
  • toBe vs toEqual: toBe object(general) equality vs deep equality
  • fixture.whenStable().then(() => {}); executes after all async operations are executed/finished
  • tick() simulates the passage of time until all async operations above are finished. Must go with fakeAsync keyword, otherwise error will appear
  • fixture.whenStable() vs tick();
    They both do the same. tick() is more prudent to use because you have to give it (in the header of the test) a fakeAsync which means that everything is called synchronously inside the test. The code after the tick() method indicates that all code above has executed (async operations above) and that you can now proceed with testing the result of these above async operations.
    Fixture.whenStable() however can give a false positive if async() is omitted in the header of the test. Therefore the test will complete before fixture.whenStable executions.
  • A Spy is a feature of Jasmine which lets you take an existing class, function, object and mock it in such a way that you can control what gets returned from functions.


Configuring Test Module

...

innerHTML

    let fixture= TestBed.createComponent(AppComponent);
    let element1= fixture.debugElement.query(By.css(".heading")).nativeElement.textContent; //must include the point prefix (.)
    expect(element1).toContain("come")
});

 OR

  it ("test input innerHTML example", async()=>{
     let fixture= TestBed.createComponent(AppComponent);
     let element2= fixture.debugElement.nativeElement.querySelector(".heading");
     expect(element2.textContent).toContain("come");
});

input HTML tag

    it ("test input input-value attribute example", async()=>{
     let fixture= TestBed.createComponent(AppComponent);
     let element1= fixture.debugElement.nativeElement.querySelector("input");
     expect(element1.getAttribute("value")).toContain("som");
});

CSS style

    it ("test input input-value attribute example", async()=>{
     let fixture= TestBed.createComponent(AppComponent);
     let element1= fixture.debugElement.nativeElement.querySelector("input");
     expect(element1.getAttribute("value")).toContain("som");
});
    it ("test css style", async()=>{
     let fixture= TestBed.createComponent(AppComponent);
     let element1= fixture.debugElement.nativeElement.querySelector("h1");
     expect(element1.style.backgroundColor).toBe("blue"); // style attribute is the key for testing css
});

Class property testing


import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

beforeEach(() => {
       TestBed.configureTestingModule({
           declarations: [AppComponent]
       });
     });

it('check title class property', async()=> {
  let fixture= TestBed.createComponent(AppComponent);
   expect(fixture.componentInstance.title).toBeDefined()
 });


Service testing

import { TestBed, async, inject } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component'
import { MyServiceService } from './my-service.service'

beforeEach(() => {
let userServiceStub = {
isLoggedIn: true,
user: { name: 'Test User'}
};

//simulate module
TestBed.configureTestingModule({
declarations: [ AppComponent],
providers: [ {provide: MyServiceService, useValue: userServiceStub } ]
});
});

it('should test service object property value', inject([MyServiceService], (userService) => {
let fixture=TestBed.createComponent(AppComponent);
fixture.detectChanges();
expect(userService.user.name).toContain('se');

}));

Pipe testing

import { TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component'
import { TryPipe} from './try.pipe'

it ("should check pipe content", async()=>{
    let piping= new TryPipe();  //create an instance of the pipe
    expect(piping.transform("")).toEqual("something"); //transform returns something initially
});

Directive testing

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { By } from '@angular/platform-browser';
import { FirstOneDirective } from './first-one.directive'
import { NO_ERRORS_SCHEMA }  from '@angular/core';

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [ AppComponent, FirstOneDirective ],
    schemas:      [ NO_ERRORS_SCHEMA ]
  }).createComponent(AppComponent);

});
it('should have skyblue css background, set from the directive', async()=> {
 //checking the code from the directive implementation
  const fixture=TestBed.createComponent(AppComponent);
  const de = fixture.debugElement.query(By.css('.nesto'));
  const bgColor = de.nativeElement.style.backgroundColor;
  console.log(de.nativeElement.textContent);
  expect(bgColor).toBe('cyan');
 });

([ngModel]) testing

  it('should pass twice, passes but because of two way data binding ngModel', async(() => {
    const fixture1 = TestBed.createComponent(ChangeRestApiComponent);
     fixture1.detectChanges();
     fixture1.whenStable().then(() => {
       let input_val = fixture1.debugElement.query(By.css('#first')).nativeElement;
       expect(input_val.getAttribute('value')).toBeNull();
       input_val.value = 'localhost';

       fixture1.detectChanges();
       input_val.dispatchEvent(new Event('input'));

       expect(fixture1.componentInstance.tempUrl).toContain('localhost');
     });
  }));

Check something to be false (not to contain a substring)

  it('should not contain full url paths, protocol e.g. http://', () => {
    component.array.forEach((item) => {
        expect(item.url.indexOf('http') === 1).toBe(false);
    });
  });

Checking html CHECKBOX element “checked” attribute

  it('check if checkbox checked attribute changed from default false to true', async() => {
    const input = fixture.debugElement.query(By.css('.className')).nativeElement;
    expect(component.testing).toBe(false);
    component.testing = true;
    fixture.detectChanges();
    expect(input.checked).toBe(true);
  });

Check value after BUTTON onClick event executes

it('check if on-button (click) event changes the value in the HTML', async() => {
     const div = fixture.debugElement.query(By.css('.clicking')).nativeElement;
     expect(component.clickMe).toBeUndefined();
     component.clickThisButton();
     fixture.detectChanges();
     expect(div.innerText).toEqual(component.clickMe);

  });

Check new INPUT value after change event executes

  it('change input value and check if change occured', async() => {
   const input = fixture.debugElement.query(By.css('.inputlast')).nativeElement;
   expect(input.value).toBe('undefined');
   component.changeMe = 'changed';
   fixture.detectChanges();
   expect(input.value).toEqual('changed');
  });

EventHandler(‘click’) testing

...

Routing testing

...

Local storage testing

...

JS quick tips

Quick theory

– JS uses camel case, lower than uppercase to write a function.
– JavaScript is a loosely typed language (no int, string, bool, char array value types…).
– Declare all variables at the top of the function.
– JavaScript uses the Unicode character set.
– JavaScript Types are Dynamic.
– All functions in JavaScript are objects.
– JavaScript functions parameters are value types.
– In JavaScript, arrays use numbered indexes, they do not support named indexes like in python, object support named indexes.
– In fact, in JavaScript, all functions have access to the scope “above” them.
– JavaScript supports nested functions. Nested functions have access to the scope “above” them. (closures)
– JS doesn’t have pointers (there are pointers but they are called references).
– Closures: when you first call the function then you just invoke the outer function, when you invoke the variable function then you actually call the inner function every time. Basically you need a „double“function call to get the closures to work, no magic.
– The difference between solo functions and and prototype functions is that prototype functions can be applied with a dot (.) where as solo function can not do that.
– Very important: the event queue cannot go into stack-overflow, only the stack can go in such state.
– No, JavaScript objects cannot have duplicate keys. The keys must all be unique. (this is important for example when removing duplicates)
–  Strict keyword– enhances the proper writing of JS. It prevents undeclared variables, it catches some common coding bloopers, throwing exceptions. it prevents, or throws errors, when relatively “unsafe” actions are taken (such as gaining access to the global object). It prevents duplicate properties, eval becomes safer.
– NaN is a Number data type and appears when an arithmetic operation which had to be executed fails. Example: parsing a string to an integer which cannot be an integer when parsed, „abc“ to int.
– JS is asynchronous (non blocking) language
– JS is single threaded, one callstack, no parallel threads (multi-threads) only event loops
– The entire code inside the script block is the main function it doesn’t need a main function explicitly like in C#, Java, C etc.
– The event loop pushes the “result” from the queue to the stack if the stack is empty.

How does JS async work?

The function is pushed to the stack, the API is called for the function, the function executes and goes to the task queue. When the stack is empty the task queue pushes onto the single threaded stack.

Application of bitwise operators in JavaScript

First of all let us revise what bitwise operators are and why you should comprehend them in 2017. Bitwise operators are operators that work on a bit or two bits (comparing them and giving a result based on the comparison) at a time.

AND ( & ) will  be 1 only if both of the bits are 1, otherwise it will be 0.
Example (all combinations): 1&1=1;  1&0=0;  0&1=0;  0&0=0;

OR ( | ) will be 1 if there is a 1 present when comparing two bits,
Example (all combinations): 1|1=1;  1|0=1;  0|1=1;  0|0=0;

XOR ( ^ ) is 1 only if one bit is 1 and the other is 0 no matter the order (1 XOR 0 =1)
(0 XOR 1=1)

NOT ( ~ ) if the bit is 0 it will go to 1 if it is 1 it will go to 0. In this case there is no comparison with other data. If you have an integer, let’s say 5 which is 0101 then the NOT will bring it to 1010.

To see the truth tables go to this website
Practical applications of bitwise operators (real life):
0X1 represents 1 in hexadecimal.


  • We check if the value is odd. If it is, the program returns true it’s not (if it is even) then the program returns false:


(value & 0x1) > 0

Explanation: Let’s say we have a value of 8 and on the other side we have 0x1. We convert them to binary numbers (that’s what the computer only understands at the most bottom level). We write the numbers one below the other and start the calculation from the most right bit to the most left bit (refer to the and operator above)

1000
0001


0000

The result is 0000 which is 0 in denary (decimal ). Zero is not greater than zero so the expression returns false. Which means that the number is even.

JS code:

console.log((8 & 0x1) > 0)
  • Use them for data encryption (encryption is all about bitwise operators)

a = 1903349;
b = 4542345;
c = 5834533;
hash = a ^ b ^ c;

The numbers will be converted to binary and will be hashed (they will be transformed in some boolean XOR equivalent data)

Conclusion:

Bitwise operators are rarely used in JavaScript (as far as I’ve seen in 5 years of coding). I suppose interviewers use them for questions for future employees to see how deep the candidate went with their programming knowledge. Still, it is good to know them because once you see them and maybe have to do something with them you will have the basic knowledge in your head and solving the problem in front of you will require less time and frustration.

So, when doing operation with bitwise operators which are nothing else but boolean operations, always have in mind the truth tables which are easy to understand and learn.

My opinion is, try to avoid them because your code looks incomprehensible to others who may in the future maintain your application. The more clearer you are the better for everyone else.

Changing border-color of HTML input element to red if an error occurs

On November 7th a question was posted on SO where the OP wanted to change the border color of the input elements to red when both inputs didn’t match a condition.

I combined the JavaScript and a little bit of JQuery to solve this.

Here is the code:

var index_one;
var index_two;

    $('#Location, #LocationTo').change(function (e) {

        index_one = $("#Location")[0].selectedIndex;
        index_two = $("#LocationTo")[0].selectedIndex;
    });
    $("#submit").click(function () {
        if ($("#Location>option").eq(index_one).text() == $("#LocationTo>option").eq(index_two).text()) {
            $('#Location, #LocationTo').css("border-color", "red");
        } else {
            $('#Location, #LocationTo').css("border-color", "black");
        }
    });

As you can see, I first fetched the indexes of the selected items and after that gave the index to the eq(index) JQuery function in order to get the element as an object and then get the text via the .text() function. If the same options were selected in both input tags then the red border color would be displayed, otherwise the black default color remains.

If you want to handle all the possible cases then add the following code:

else if($("#Location>option").eq(index_one).text() =="Please Select")
    {
        alert ("Select an option");
    }
      else if($("#LocationTo>option").eq(index_one).text() =="Please Select")
    {
        alert ("Select an option");
    }

Here is the fiddle to see the code in action: http://jsfiddle.net/eugensunic/eg8k4vL7/1/

Google maps API usage limits (2015)

Do I need an API key?

Answer: in the early days of google maps you did not require an API key (it is still possible to not have one due to backwards compatibility) however, today it is recommended that you generate an API key for google maps V3. Also, have in mind that some features are not available without the API key.

Generate your google maps API key HERE.

If you want to inform your self more about the API key, here is the official page that will tell you how to get started with it and how to include it to your project,

url: https://developers.google.com/maps/documentation/javascript/tutorial

What are the usage limits?

Answer: If your site gets 25 000 map loads or more every single day, for more than 90 days in a row, the google team will get in touch with you (they are well aware of your google maps usage). If however you don’t think your google maps will generate such an amount of traffic then do the following:

  • Modify your application so that your usage is less than 25 000 map loads per day.
  • Enroll for automated billing of excess map loads in the Google Developers Console.
  • Purchase a Google Maps API for Work license.

Here is the official page for the limits,

url: https://developers.google.com/maps/documentation/javascript/usage#quota

To sum it all up: If you can predict huge traffic on your website (and using the google maps API within your website), then once again read carefully the docs and see what further steps need to be taken, otherwise you can experiment with google maps as much as you want.

Google maps zoom parameter inside an URL not working (2015)

On September 28th a question was posted on Stackoverflow where the OP complained about the zoom parameter INSIDE HIS URL. He tried to solve the problem by specifying the zoom parameter using the letter z and the value, example: z=12 (setting the zoom parameter to 12). The problem is, this doesn’t work anymore.

In google maps v2 and even in the v3 the following link: http://maps.google.com/?q=38.6531004,-90.243462&z=12 would have worked without any issue. However, for some reason the Google team decided to change it and not to allow anymore this kind of adjustment to work anymore (I must say that I’m surprised with that, I’m still not sure what was the reason for removing the documentation and functionality of the above link).

Fortunately, I found a hack on how to still use the Google maps z parameter and to get the desired result with it. Allow me to make a group of links which do not work, which work but with not getting 100% what you want.

Examples where the z parameter doesn’t work (try changing the z value to see that the parameter always holds a constant value):

Examples where the z parameter works but you do not get the pinpoint (try changing the z value to see that the parameter affects the map):

(Note: after clicking on google maps you will get a gray marker which appears and quickly disappears)

Example which works (by changing the zoom parameter the map is being affected and the red pinpoint is shown):

https://maps.google.com/?q=38.6531004,-90.243462&ll=38.6531004,-90.243462&z=3

The hack included adding the q attribute parameter (represents the search query) and the II attribute/parameter(represents the latitude and longitude of the map center point).

I hope this will work for at least a year from now on. If there is any issue with the link or if it doesn’t work anymore please leave a comment.

 LINK to SO question&answer

Strings, Objects (immutability)

Topic includes

  • immutability
  • literal string
  • methods/functions
  • value type
  • reference type
  • object
  • class
  • verbatim string

Today I’ll discuss what does the heading above mean and why it is important or maybe it isn’t?

When anybody starts to program the first thing that will come up to him are strings. Strings are EVERYTHING in programming, you can do whatever you like with them you can also convert other data type to strings and make some useful operations and then again convert to its primitive type ( I do that very often). At one point you will have to get familiar with the basic methods that strings provide. If you go deeper you will see that you can substitute many string operations using regex.

What does immutable mean?

If you asked a layman what does immutable mean he’ d most probably say something that cannot MUTATE (something that can not change).

I remember when I first heard this word in programming, I immediately thought of a monster who can mutate (can change its appearance, structure, look ect.). Even tough this doesn’t make sense since we want something immutable here.

I must say that I picked up the term really quickly and I understood what it meant but didn’t go deeper with my mind to it.

Enough talking for now, let’s start with an example:

var name="Paul";
name.concat(" and Jenny");
alert(name);

The question is, why doesn’t the literal string “&Jenny” get applied to the name, why doesn’t it change the value of name when the concat() function is applied?? The answer can be found in the title of-course, strings are immutable. This means that the variable “name” is of value type which means that it stores the data directly to the memory and access it as well.

definition of value types (source url:https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx): A data type is a value type if it holds the data within its own memory allocation.

This withdraws the reference types, strings are immutable because the are not reference type rather than that, they are value types as mentioned above.

definition of reference type (source url:https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx): A reference type contains a pointer to another memory location that holds the data.

One thing to clear up here. No matter which type of is the variable “name” the concat() function returns the result “Paul & Jenny” BUT DOES NOT APPLY IT TO THE VARIABLE NAME. It just stays there “hanging in the air”.

example:

var name="Paul";
name.concat(" and Jenny");
alert(name.concat(" and Jenny"));

In the alert box you will see the result “Paul & Jenny” and you will wonder, how did this concatenate now, but if we print out (again showing a alert box) the variable name “Paul & Jenny” the concatenation is not applied and it does not show up? That’s because the function concat() returns the new value and the alert box just display’s it.

To make a conclusion: value types can not be altered/modified/changed. Reference types can be changed.

How do I concat my string literal to the variable string “Paul”?

The easiest solution here would be to override the variable ( replacing the variable name by applying a new content to it, see the following example)

example:

var name="Paul";
name=name.concat("and Jenny");
alert(name);

The output of name will now be “Paul & Jenny”

Using a string like an array is extremely useful sometimes but the immutability kicks in and we have to write some extra code to overcome this state.

example:

 var name="Paul";
 name[0]="r";
 alert(name);

As you can see in the output, the name remains exactly the same (although we’ve “changed” the first letter to ‘r’)By now you should know the answer why this is the case, but, just in case, strings are immutable, strings are value types hence not reference types. Na altering/modifying/changing whatsoever.

Let’s now modify the string in the way that we could not do it before, but first let’s make a small introduction to Objects.

When I started to learn objects (OOP- object oriented programming) things didn’t make sense because I always and I must says once again, always thought in this way: “Why would I use something else if I can achieve that with the previous known stuff”.

Every time someone asks me about objects, I say to him :Objects or OOP programming is used to make things more tidy, more neater.” I didn’t mention more effective, less code or anything else apart from the sentence above.

I always avoided functions/methods, classes ect. because I liked to get my things done quickly just writing the code going step by step, line by line and finding a solution without this fancy stuff which was good until bigger projects came… Then I just new that I had to involve the objects/classes (object!=class) to get my things done quicker!

I’ don’t want to go too deep into objects and classes especially not in the JavaScript sense, since JavaScript does not have a full OOP structure like C# for example, but I will say the most important part of it.

You can think of an object as a wrapper where you wrap inside your properties and functions which you later use by specifying the object name and accessing it’s properties or methods via the . symbol

example:

var person = {
 firstName: "Paul",
 lastName : "Sanders",
 fullName : function() {
 return person.firstName+" "+ person.lastName;
 }
};
alert(person.fullName());

You can see that we have an object which encapsulates (wraps around) properties and methods and we are accessing the method .fullName() via the . symbol (as said) and we are also able to access it because we used the object before “person”.

I will stop here with the explanation of objects, I think that this is more than enough for this post (at the end of the article you can find a short explanation of objects and classes)

Let’s get back now to reference types, why? Because we involved object in the whole story… TO BE CONTINUED…

Incredibly good links on immutability:

 

Adding text from div to another div atribute inside a (stackoverflow problem)

Problem posted: 07/08/2015

url: http://stackoverflow.com/questions/31871404/how-to-add-text-in-the-data-attribute-using-jquery
fiddle: http://jsfiddle.net/eugensunic/0kourse6/4/

Problem description:

The title says it all. The user wanted to fetch the text from the div tag and assign it to the

attribute which had a parent li.

Solution to the problem:

var array=[];
$('.pin_head > div').each(function (index,obj) { 

   array[index]= $(this).text();

});

$('li > div').each(function (index,obj) {
    var data= $(this).attr("data-col",array[index]);
});

Formating characters – indentation&comma (stackoverflow problem)

Problem posted: 08/08/2015

url:  http://stackoverflow.com/questions/31890301/javascript-string-split-based-on-value/31890361#31890361
fiddle: https://jsfiddle.net/eugensunic/kphe5fbL/13/

Problem description:

Format the current string :
Landing Hits: 0Rewards Hits: 0Facebook Posts: 0Twitter Tweets: 0Twitter Autofollows: 0Instagram Photos: 0Instagram Likes: 0Instagram Votes: 0Pinterest Pins: 0Form Submissions: 0Submissions: 0Engagement: 0Views: 0Prints: 0″

to the following output:
Landing Hits: 0, Rewards Hits: 0, Facebook Posts: 0, Twitter Tweets: 0, Twitter Autofollows: 0, Instagram Photos: 0, Instagram Likes: 0, Instagram Votes: 0, Pinterest Pins: 0, Form Submissions: 0, Submissions: 0, Engagement: 0, Views: 0, Prints: 0″

The OP wanted to add a comma after the number (the number can be positive or negative greater than and lower than 0, not only 0)

Solution to the problem:

var c = "Landing Hits: -345Rewards Hits: 0Facebook Posts: 0Twitter Tweets: 034534532Twitter Autofollows: 0Instagram Photos: 0Instagram Likes: 0Instagram Votes: 0Pinterest Pins: 0Form Submissions: 0Submissions: 0Engagement: 0Views: 0Prints: 0";
var array = []
var counter = 0;
var num;
var dup = "";
for (var i = 0; i<c.length; i++) {
 dup += c[i];
 if (c[i]==":"){dup+=" ";}
 if (!isNaN(c[i]) && isNaN(c[i+1]) && c[i]!=" ") {
 dup += ", "
 }
}
 alert(dup);

After that I also decided to make a function which would get the length of each number after the colon ":" in the same sequence.

var c = "Landing Hits: 345Rewards Hits: 0Facebook Posts: 0Twitter Tweets: 034534532Twitter Autofollows: 0Instagram Photos: 0Instagram Likes: 0Instagram Votes: 0Pinterest Pins: 0Form Submissions: 0Submissions: 0Engagement: 0Views: 0Prints: 0";
var array = []
var counter = 0;
var num;
var dup = "";
var i=0;
for (var j=0; j<c.length; j++)
{
if (!isNaN(c[j]) && c[j]!=" ") // because js interprets " " as 0 if applied on isNan() evaluates to false so I hade to include the other part inside the if as well
{
counter++;
if (isNaN(c[j+1]))
{
array[i]=counter;
i++;
counter=0;
}
}
}
console.log(array[0]);