0

So, i wanted to check if an ad was displayed on an allowed website using javascript. I used a methodology explained in that post Determine if string is in list in JavaScript.

Here is my code :

async function ImpCertification(tx) {

    Impression = await getAssetRegistry('org.example.basic.Impression')

    const source = Impression.PrintedSite

    whitelist = ["Youtube", "Google", "Facebook", "Twitter"]

    if (whitelist.indexOf(source) < 0) {
        // Checks if source in whitelist
        throw new Error ('This impression does not respect branding')
    }

    // Checks every necessary conditions to validate impression
    if (whitelist.indexOf(source) >=0) {
        // Save the old value of the asset.
        const oldValue = Impression.Valid;

        // Update the asset with the new value.
        Impression.Valid = true;

        // Get the asset registry for the asset.
        const assetRegistry = await getAssetRegistry('org.example.basic.transaction.ValidateImpression');
        // Update the asset in the asset registry.
        await assetRegistry.update(Impression);

        // Emit an event for the modified asset.
        let event = getFactory().newEvent('org.example.basic', 'Validation');
        event.asset = tx.asset;
        event.oldValue = oldValue;
        event.newValue = true;
        emit(event);
    }
    await null
}

I'm developing an hyperledger business network so some parts maybe seem exotic but I must bring your attention to the whitelist/indexOf stuff. It just doesn't work although I get the logic of it.

I tried to enter every element of the whitelist in Impression.PrintedSite but it keeps throwing the "this impression does not respect branding" error everytime, wether it is right or not.

Before you ask, I checked for caps in Impression.PrintedSite, it is a string, I tried the other method suggested using booleans and "includes" but it just won't work. Halp !

Coolkat64
  • 11
  • 5

2 Answers2

0

At first, make sure that the string that you pass to indexOf is an actual string:

typeof <your-string-variable> === 'string'

To check if a string is in your list I suggest using ES6 Array.prototype.includes() :

['a', 'b', 'c'].includes('b')

To check if a string is a substring of the strings in your list combine Array.prototype.includes() method with String.prototype.includes() method:

(I also used ES6 reduce there to simplify the expression)

['hello', 'world', 'my', 'name', 'is', 'johny', 'cash'].reduce((current, item) => current || item.includes('substring_to_search'), false);

inaumov17
  • 1,329
  • 11
  • 18
  • Thank you for your insight, unfortunately I discovered that Hyperledger Fabric runtimes just do not support ES6. EDIT: I checked an old development log, my bad, ES6 is supported since January. I'm digging into it right now – Coolkat64 Jun 20 '18 at 12:37
0

So long story short, since the ID of the object "impression" wasn't filled in the function the constant was just empty because fetching information that didn't exist.

Therefore since null is not in whitelist the indexof returned -1 and every time the program would enter this condition and return the error.

This simple fix is

async function ImpCertification(ValidateImpression) {
    imp = ValidateImpression.impression
    const source = imp.PrintedSite

    ect...

}

where "ValidateImpression" is the transaction which points to the Impression asset through an ID

asset Impression identified by ImpID {
    o String ImpID
    o String PrintedSite
}    

transaction ValidateImpression {
        --> Impression impression
}
Coolkat64
  • 11
  • 5