requiring lodash modules with webpack - module

I used to use lodash.js without any packaging like below:
if (_.isFunction(myFunc)) { ... }
Recently, I started using webpack. Now, it seems many functions such as isFunction are not part of the core module. So, the following works:
var _ = require("lodash/core");
var _isFunction = require("lodash/isFunction");
However, the above changes the syntax when I used lodash without webpack (no dot). Should I require like below:
_.isFunction = require("lodash/isFunction")
so, that to maintain the same syntax?

When you do something like the following, you import everything under one big lodash object:
var _ = require('lodash');
_ (or whatever var you choose) will be filled with a bunch of functions:
_ = {
isX: function...
isY: function...
// ... etc
}
Ie: it brings everything in.
When you do the following, it will import only the required module directly into the variable:
var anynameX = require('lodash/isX');
var anynameY = require('lodash/isY');
anynameX and anynameY can be anything.
In other words:
_.isX === anynameX;
_.isY === anynameY;
So to answer your last question, you could do:
_.anynameX = require('lodash/isX');
but only if _ already exists (and isn't frozen), for example:
var _ = {};
_.anynameX = require('lodash/isX');

Related

Javascript code not working after upgrade to karate 0.9.3

The below function in feature files was working for version 0.9.2. Upgraded to 0.9.3 and this gives error : javascript function call failed: Index: 0.0, Size: 0. Code below:
var cnd = ['test1','test2'];
function set_filter(arg)
{
var i;
var filter = {filterValues:[]};
for(i=0;i<arg.length;i++)
{
filter.filterValues[i] = arg[i];
}
return filter;
}
set_filter(cnd)
Also i was earlier able to push values in a javascript array using below, but this has also stopped working in 0.9.3. Get error:javascript function call failed: TypeError: arr.push is not a function
var arr = [];
arr.push('test1','test2');
Try the scenario below that works in 0.9.2 but reports error (mentioned above) in 0.9.3
Scenario: JS test
* def filter_template =
"""
function() {
var filter_params = {
filterValues:[]
};
return filter_params;
}
"""
* def template = call filter_template
* def filter_condition = ['test1','test2']
* def setFilter =
"""
function(arg) {
var i;
var filter = arg.filter_template;
for(i=0;i<arg.condition.length;i++)
{
filter.filterValues[i] = arg.condition[i];
}
return filter;
}
"""
* def getFilter = call setFilter { filter_template: '#(template)', condition: '#(filter_condition)' }
* print getFilter
Help is much appreciated.
We've made the JS conversions stricter, everything will be a Java collection behind the scenes. If you make this change, things will start working:
filter.filterValues.set(i, arg.condition.get(i));
The same goes for push() - use add() or karate.appendTo(varname, value) instead.
My strong recommendation is don't use too much of JS logic especially loops. Karate has functions such as map(), forEach() and repeat() to solve for these needs. Please refer the docs here: https://github.com/intuit/karate#loops
You will thank me later because it will make your scripts easier to understand and maintain. One reason why this is needed is to pave the way for us to change the JS engine in the future.

rollup equivalent of "browserify -r"

I need to force some modules into my bundle, as they are required dynamically through some code like below:
var moduleName = "someModule";
var myModule = require(moduleName);
I was using browserify to bundle this (through browserify -r or the API equivalent).
I am trying to switch to rollup and I don't figure out how to do this with rollup. Basically, I just want to force some modules into the bundle, and make them available globally through the require statement.
I think the key here is to use the new ES6 module syntax as described in the Rollup documentation. This will also give Rollup the possibility to apply features like chunking and tree-shaking.
Another important thing is to make it explicit what might get imported. By that I mean to use statements like 'import('./module1.js')' instead of 'import(some_variable)'. It is hard for Rollup to figure out all possible contents of the variable which gets used in the import. Therefore I would use explicit file names here but wrap everything in some kind of if/else condition.
Consider the following example:
File ./src/main.js:
let num = Math.random() * 10;
let condition = Math.round(num % 3);
let mod;
if (condition === 1) {
import('./module1.js').then((module)=> {
log(module);
});
} else if (condition === 2) {
import('./module2.js').then((module)=> {
log(module);
});
} else {
import('./module3.js').then((module)=> {
log(module);
});
}
function log(module) {
mod = module;
console.log(mod.test());
console.log('Done');
}
File ./src/module1.js:
function test() {
return 'This is 1!';
}
export { test };
The files module2.js and module3.js are the same like module1. The only difference is that they log 'This is 2!' and 'This is 3!'.
The Rollup config looks like this:
const production = !process.env.ROLLUP_WATCH;
export default {
inlineDynamicImports: true,
input: 'src/main.js',
output: {
dir: 'public/',
format: 'esm',
sourcemap: true
}
};
If you run 'rollup -c' then there will be one file './public/main.js'. This bundle will include all three modules. Usually Rollup would create main.js and three chunks. By using the setting 'inlineDynamicImports=true', Rollup puts everything in one file.
You can also change the format in the Rollup config to 'iife' (or amd, cjs, umd) if you want to.

Vue - removing all spaces from a string from Firestore database

I am still learning Vue. I know how to remove all spaces from a string using Javascript, such as:
var str = " a b c d e f g ";
var newStr = str.replace(/\s+/g, '');
I can't figure out how to implement this in Vue.
I would like to take a string from my Firestore database, say a field called "title1", with a value of "This is my string" and remove all spaces so it says "Thisismystring". Then I want to be able to use that string in my Vue app in the same way I would use title1... like a variable called title1nospaces.
I'm not sure if I should be using a computed property or a method. Anything I've tried always comes back as "title1nospaces" is not defined on the instance but is referenced during render".
Any help appreciated.
var str = " This is a test ";
var new_str = str.split(' ').join('');
console.log(new_str); // 'Thisisatest'
In your vue app, you should add a mixin and in that mixin you should implement a method that takes an input with spaces and it should return the output as a string without a spaces (or formatted string).
E.g.
let myApp = new Vue({
mixins: [CommonUtils],
});
CommonUtils.js code ( I am using ES6 syntax):
export default {
methods: {
myStringFormattingFun(input) {
// Do your magic and return the formatted string
}
}
}
OR you can just implement the function in your myApp component (main component).

Renaming models in database with existing data when using RavenDb

Is there any 'easy' way to rename models in RavenDb when the database already has existing data? I have various models which were originally created in another language, and now I would like to rename them to English as the codebase is becoming quite unmaintainable. If I just rename them, then the data won't be loaded because the properties don't match anymore.
I would like the system to automatically do it on first load. Is there any best way how to approach this? My solution would be:
Check if a document exists to determine if the upgrade has been done or not
If upgrade has not been done, execute patch scripts to update fields
Update document to know that the upgrade has been done
I'd recommend you create new documents from the old documents.
This can be done pretty easily using patching via docStore.UpdateByIndex.
Suppose I had an old type name, Foo, and wanted to rename it to the new type name, Bar. And I wanted all the IDs to change from Foos/123 to Bars/123.
It would look something like this:
var patchScript = #"
// Copy all the properties from the old document
var newDoc = {};
for (var prop in this) {
if (prop !== '#metadata') {
newDoc[prop] = this[prop];
}
}
// Create the metadata.
var meta = {};
meta['Raven-Entity-Name'] = newCollection;
meta['Raven-Clr-Type'] = newType;
// Store the new document.
var newId = __document_id.replace(oldCollection, newCollection);
PutDocument(newId, newDoc, meta);
";
var oldCollection = "Foos";
var newCollection = "Bars";
var newType = "KarlCassar.Bar, KarlCassar"; // Where KarlCassar is your assembly name.
var query = new IndexQuery { Query = $"Tag:{oldCollection}" };
var options = new BulkOperationOptions { AllowStale = false };
var patch = new ScriptedPatchRequest
{
Script = patchScript,
Values = new Dictionary<string, object>
{
{ nameof(oldCollection), oldCollection },
{ nameof(newCollection), newCollection },
{ nameof(newType), newType }
}
};
var patchOperation = docStore.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName", query, patch, options);
patchOperation.WaitForCompletion();
Run that code once at startup, and then your app will be able to work with the new name entities. Your old entities are still around - those can be safely deleted via the Studio.

dojo.requireIf does not allow local variables

I've been trying to use dojo.require(If) with a local variable to dynamically load a module on a page based on a condition.
// note: dojo v1.4
djConfig = {
debugAtAllCosts: true
};
Example 1 (does not work):
(function() {
var nameOfClass = "Two";
dojo.require("my.namespace." + nameOfClass);
dojo.addOnLoad(function() {
var oneOrTwo = new my.namespace[nameOfClass]();
});
}());
Error: ReferenceError: nameOfClass is not defined.
Example 2 (does not work):
(function() {
var nameOfClass = "Two";
dojo.requireIf(nameOfClass == "One", "my.namespace.One");
dojo.requireIf(nameOfClass == "Two", "my.namespace.Two");
dojo.addOnLoad(function() {
var oneOrTwo = new my.namespace[nameOfClass]();
});
}());
Error: ReferenceError: nameOfClass is not defined.
Example 3 (works):
(function() {
window.nameOfClass = "Two";
dojo.requireIf(window.nameOfClass == "One", "my.namespace.One");
dojo.requireIf(window.nameOfClass == "Two", "my.namespace.Two");
dojo.addOnLoad(function() {
var oneOrTwo = new my.namespace[nameOfClass]();
});
}());
For some reason, it appears as though require and requireIf only allow global variables inside them. Is that a current limitation, or am I just doing something wrong?
Update 1:
Therefore, if I understand you (#Maine, #jrburke) correctly, this is a limitation of the debugAtAllCosts? If the above code is built as cross-domain (adding the xd file prefix / suffix) and is executed -- it will work as expected?
If that is the case, then what is the proper way of locally testing code that will be executed as cross-domain, without making the actual build?
That also makes me question the motivation for pre-parsing the dojo.require(s). If the loader_xd will not (or rather can not) pre-parse, why is the method that was created for testing/debugging doing so?
Update 2:
Since the two questions in the Update 1 above are not closely related to this one, I've moved them out into a separate discussion.
This is because requireIfs are parsed with regexps as the very first thing, and executed before the normal program flow.
If you'll grep Dojo source for requireIf, you should find this kind of lines handling it (loader_xd.js):
var depRegExp = /dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\s*\(([\w\W]*?)\)/mg;
The condition is then executed with eval in global scope, and not as a part of normal flow.
To clarify more of what Main said, this is an issue with the XD loader in Dojo. debugAtAllCosts: true uses the XD Loader. If you just use the normal Dojo loader without debugAtAllCosts, it is not an issue. Also, attaching the module module name as a property on a publicly visible module would also avoid the issue.