Accessing NetSuite modules from Config file scripts (SuiteScript) - javascript

I am trying to build a JS file to place in the file cabinet to reference my most used functions I constantly rebuild. I have been able to access it by placing the script in the file cabinet and using the #NAmdConfig to reference the functions. However, I cannot access the NetSuite modules in these scripts. I cut most of the function off in my example, but if I can return that to my original Map/Reduce script that will suffice. How can I have a third party script of my most used functions while still having access to the NetSuite modules?
/**
* #NApiVersion 2.1
* #NModuleScope public
*/
var MattsFunctions = {
dynamicTransactionSearch:
function (sentId) {
var thisRecord = record.load({
type: record.Type.SALES_ORDER,
id: sentId
})
return thisRecord.id
}
}
I have also tried
/**
* #NApiVersion 2.1
* #NModuleScope public
*/
define(['N/search', 'N/record'],
(search, record) => {
var exports = {};
var MattsFunctions = {
dynamicTransactionSearch:
function (sentId) {
var thisRecord = record.load({
type: record.Type.SALES_ORDER,
id: sentId
})
return thisRecord.id
}
}
exports.MattsFunctions = MattsFunctions
return exports
})

Figured it out. Simply pass the module over in the function you're calling, of course!

Related

React Module parse failed: Unexpected token (1:48)

Can someone help me? I just create react app then I start it immediately. Then I got an error something like this. I don't know much about webpack.
CMD
./src/index.js 1:48
Module parse failed: Unexpected token (1:48)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
> $RefreshRuntime$ = require('C:/Users/LENOVO/Mine/project-new/node_modules/react-refresh/runtime.js');
| $RefreshSetup$(module.id);
|
I just type npx create-react-app ./ in the directory then npm start then this error happened.
I have tried to make 3 react app and same thing happened and i never touch the webpack before.
App.js
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
This is my webpack.config.js
https://pastebin.com/NVHdYGGN
#pmmmwh/react-refresh-webpack-plugin/loader/index.js
// This is a patch for mozilla/source-map#349 -
// internally, it uses the existence of the `fetch` global to toggle browser behaviours.
// That check, however, will break when `fetch` polyfills are used for SSR setups.
// We "reset" the polyfill here to ensure it won't interfere with source-map generation.
const originalFetch = global.fetch;
delete global.fetch;
const { SourceMapConsumer, SourceMapGenerator, SourceNode } = require('source-map');
const { Template } = require('webpack');
/**
* Generates an identity source map from a source file.
* #param {string} source The content of the source file.
* #param {string} resourcePath The name of the source file.
* #returns {import('source-map').RawSourceMap} The identity source map.
*/
function getIdentitySourceMap(source, resourcePath) {
const sourceMap = new SourceMapGenerator();
sourceMap.setSourceContent(resourcePath, source);
source.split('\n').forEach((line, index) => {
sourceMap.addMapping({
source: resourcePath,
original: {
line: index + 1,
column: 0,
},
generated: {
line: index + 1,
column: 0,
},
});
});
return sourceMap.toJSON();
}
/**
* Gets a runtime template from provided function.
* #param {function(): void} fn A function containing the runtime template.
* #returns {string} The "sanitized" runtime template.
*/
function getTemplate(fn) {
return Template.getFunctionContent(fn).trim().replace(/^ {2}/gm, '');
}
const RefreshSetupRuntime = getTemplate(require('./RefreshSetup.runtime')).replace(
'$RefreshRuntimePath$',
require.resolve('react-refresh/runtime').replace(/\\/g, '/')
);
const RefreshModuleRuntime = getTemplate(require('./RefreshModule.runtime'));
/**
* A simple Webpack loader to inject react-refresh HMR code into modules.
*
* [Reference for Loader API](https://webpack.js.org/api/loaders/)
* #this {import('webpack').loader.LoaderContext}
* #param {string} source The original module source code.
* #param {import('source-map').RawSourceMap} [inputSourceMap] The source map of the module.
* #param {*} [meta] The loader metadata passed in.
* #returns {void}
*/
function ReactRefreshLoader(source, inputSourceMap, meta) {
const callback = this.async();
/**
* #this {import('webpack').loader.LoaderContext}
* #param {string} source
* #param {import('source-map').RawSourceMap} [inputSourceMap]
* #returns {Promise<[string, import('source-map').RawSourceMap]>}
*/
async function _loader(source, inputSourceMap) {
if (this.sourceMap) {
let originalSourceMap = inputSourceMap;
if (!originalSourceMap) {
originalSourceMap = getIdentitySourceMap(source, this.resourcePath);
}
const node = SourceNode.fromStringWithSourceMap(
source,
await new SourceMapConsumer(originalSourceMap)
);
node.prepend([RefreshSetupRuntime, '\n\n']);
node.add(['\n\n', RefreshModuleRuntime]);
const { code, map } = node.toStringWithSourceMap();
return [code, map.toJSON()];
} else {
return [[RefreshSetupRuntime, source, RefreshModuleRuntime].join('\n\n'), inputSourceMap];
}
}
_loader.call(this, source, inputSourceMap).then(
([code, map]) => {
callback(null, code, map, meta);
},
(error) => {
callback(error);
}
);
}
module.exports = ReactRefreshLoader;
// Restore the original value of the `fetch` global, if it exists
if (originalFetch) {
global.fetch = originalFetch;
}
babel-loader/lib/index.js
https://pastebin.com/sXm9sz0n
Thanks in advance
+There seems to be an issue with the new release 4.0.2 of create-react-app [Reference].
You can use the previous, 4.0.1, by doing the following.
Edit package.json and change the "react-scripts" value to "4.0.1".
Run npm install.
Run npm start.
In my case I had a single quote character ' in my PC's name (e.g. dummy'sPC) which caused react-scripts package to crash in version 4.0.2 and 4.0.3 (but not in 4.0.1 which was interesting to me).
After moving project to a higher level folder (e.g. C:/Users/my-app) and installing node modules everything was working properly.
At the end I can use react-scripts v4.0.3 but only when project's path doesn't contain dummy'sPC string in it.
I had the same problem, and what I did was like mentioned in the above comment, I changed the "react-scripts" value in package.json to 4.0.1 and ran npm install again. Then npm start
and it worked pretty well. Did you use the same method or what method you followed in solving this problem?
It's simple
just check all the folder's names in the file path.
if any folder has ' symbol like "rifat's folder" , remove the 's
and it will work
it's basically a rename issue

Issue Searching NetSuite - nlapiSearchRecord

I am having trouble understanding what this error means.
org.mozilla.javascript.EcmaError: ReferenceError: "nlapiSearchRecord"
is not defined. (/SuiteScripts/PreventDuplicateCustomer.js#35)
I am attempting to create a script which searches for a duplicate record based on a specific field which is supposed to be unique. I would like to prevent creating duplicate 'CUSTOMER' records in NetSuite using the following script.
'
Does anyone see anything that jumps of the page as wrong with the code below?
// 2.0
define(["N/error", "N/log"], function (err, log) {
/**
* User Event 2.0 example showing usage of the Submit events
*
* #NApiVersion 2.x
* #NModuleScope SameAccount
* #NScriptType UserEventScript
* #appliedtorecord customer
*/
var exports = {};
function beforeSubmit(scriptContext) {
log.debug({
"title": "Before Submit",
"details": "action=" + scriptContext.type
});
if (doesCustomerExist(scriptContext)) {
throw err.create({
"name": "DUPLICATE_SFDC_ACCOUNT_ID",
"message": "Customer Already Contains SFDC Account Id",
"notifyOff": true
});
}
}
function doesCustomerExist(scriptContext) {
var sfdcAccountId = scriptContext.newRecord.getValue('custentitysfdc_account_id');
if(sfdcAccountId == null || sfdcAccountId == '') return false;
var searchFilter = new nlobjSearchFilter('custentitysfdc_account_id', null, 'is', sfdcAccountId, null);
var searchResult = nlapiSearchRecord('customer', null, searchFilter, null);
return (searchResult != null && searchResult.length > 0);
}
exports.beforeSubmit = beforeSubmit;
return exports;
});
nlapiSearchRecord() is a SuiteScript 1.0 function and you're trying to call it from a SuiteScript 2.0 script.
You need to add the N/search module to your 2.0 script and use the functionality provided in that module to perform a search. In the NetSuite help documentation, navigate to SuiteCloud -> SuiteScript 2.0 -> SuiteScript 2.0 API -> SuiteScript 2.0 Modules -> N/Search Module to learn how to perform a search with SuiteScript 2.0.

RequireJS no define() callbacks getting called after optimization

I am working on a web app that uses requireJS and angular. The solution is fine however I am having issues after optimization.
The way I build the application is by way of r.js. I execute it targeting my main.js that has a define() statement in it that points to all the other files in the solution as dependencies. It then generates a new main.js in my bin/ directory with all the js files it referenced concatenated into the one main.js file. So far so good.
However when I try to load the app in the browser with the optimized js, I notice that none of the define() callbacks ever get called, not even the ones with no dependencies ([]) As far as my knowledge of requireJS, modules' callbacks are executed as soon as all dependencies are resolved.
This all works just fine when the js files are all in their respective locations, with anonymous names, pre build. Its the same exact js just all in one file, so I have no idea what could be different. Other than the optimizer gave the modules names (which is what its supposed to do)
The only thing I can think of is that I am missing a bootstrapping 'require' call to the main module (which is at the bottom of the following optimized file) but I don't have any call to 'require' in my non-built solution and it works just fine.
My script that calls r.js is in a directory called 'build/' which is a sibling of 'js/' which is the root directory of where my js is.
Example of my issue: that first define('../js/common/module',[],function()... its callback never gets called despite the fact that there are no dependencies.
Does anyone know what the issue is? Any help would be much appreciated.
define('../js/common/module',[], function () {
return {
app: angular.module('common', []),
ngContext: true
}
});
define('../js/customer_account_list/module',['../common/module'], function () {
return {
app: angular.module('customer_account_list', ['common']),
ngContext: true
}
});
define('../js/mod',['./customer_account_list/module'], function () {
angular.module('app', ['customer_account_list']);
});
define('../js/common/service/app_config',['../module'], function (module) {
/**
* #class appConfigService
* #memberOf common.service
* #description calls back to the server to get the application configuration
**/
var appConfigService = function () {
url = window.location.protocol + '//' + window.location.host + window.location.pathname + 'config.json';
var configReq = new XMLHttpRequest();
configReq.open("GET", url, false);
configReq.send();
return JSON.parse(configReq.response);
}
if (module.ngContext) {
module.app.service('appConfig', appConfigService);
}
});
define('../js/common/service/feature_manager',['../module'], function (module) {
/**
* #class featureManagerServ
* #memberOf common.service
* #description manages the set of features in the product portal
**/
function featureManagerServ(appConfig) {
this.featuresEnabled = {
'customer_account_list': appConfig.features['customer_account_list']
};
/**
* #function
* #memberOf common.service.featureManagerServ
* #param {string} featureKey - feature identifier
* #description computes whether or not the feature should be enabled
**/
this.featureEnabled = function (featureKey) {
return !!this.featuresEnabled[featureKey];
};
/**
* #function
* #memberOf common.service.featureManagerServ
* #param {string} featureKey - feature identifier
* #param {Object} directive - Ng directive
* #description handles whether or not the feature will be bootstrapped
**/
this.bootstrapFeature = function (featureKey, directive) {
if (this.featureEnabled(featureKey)) {
return directive;
} else {
}
};
};
if (module.ngContext) {
module.app.service('featureManager', ['appConfig', featureManagerServ]);
}
});
define('../js/customer_account_list/directives/customer_account_list_ctrl',[], function () {
function customerAccountListCtrl($scope, customerAccounts) {
$scope.customerAccounts = customerAccounts.getCustomerAccounts();
$scope.onAccountClick = function (ind) {
var s = 0;
}
}
return ['$scope', 'customerAccounts', customerAccountListCtrl];
});
define('../js/customer_account_list/directives/customer_account_list',['../module', './customer_account_list_ctrl'], function (module, ctrl) {
/**
* #class customerAccountList
* #memberOf customer_account_list.directive
* #description customer account list component
**/
module.app.directive('customerAccountList', ['featureManager', function (featureManager) {
return featureManager.bootstrapFeature('customer_account_list', {
restrict: 'E',
templateUrl: 'js/customer_account_list/views/customer_account_list.html',
scope: {
url: '='
},
controller: ctrl
});
}]);
});
define('../js/customer_account_list/service/customer_accounts',['../module'], function (module) {
/**
* #class customerAccountsServ
* #memberOf customer_account_list.service
* #description provides list of customers user is authenticated to view/edit
**/
function customerAccountsServ($http, appConfig) {
/**
* #function
* #memberOf customer_account_list.service.customerAccountsServ
* #description provides list of customers user is authenticated to view/edit
**/
this.getCustomerAccounts = function () {
return ['AcmeFood', 'AcmeCoffee','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9'];
}
}
if (module.ngContext) {
module.app.service('customerAccounts', ['$http', 'appConfig', customerAccountsServ]);
}
});
define('../js/main.js',['./mod',
'./common/module',
'./common/service/app_config',
'./common/service/feature_manager',
'./customer_account_list/module',
'./customer_account_list/directives/customer_account_list',
'./customer_account_list/directives/customer_account_list_ctrl',
'./customer_account_list/service/customer_accounts'],
function () {
angular.element().ready(function () {
angular.bootstrap(document, ['app'], {
strictDi: false
});
});
});

How to include js files in header of wordpress pages that are activated on-click

I am attempting to use wordpress to build a website that integrates google maps. I am doing some overlays with the maps and use the google developers API and Python to make the appropriate javascript. I have successfully written the js files and Python necessary to accomplish this.
My website is built in Worpress and I would like add a page (not the home page) that has n links and each one would populate a box with the corresponding map. I can take care of the layout and design issues but I am at a loss on how to:
a) Include the javascript as a file that
b) gets called upon clicking the link and thus populates that map without calling a new page
That is, the javascript is HUGE because it may include thousands of lat/lon points. Therefore including n of these written into the header is unreasonable. I want to simply call it from filename.js when the link is clicked.
There is a plugin that allows me to include whatever I want in the header. So, if I can find out where to put the *.js files (or txt file) in the directory tree and how to have the corresponding file activated upon click I should be good. Thanks!
This Display different maps with onClick event - Google Maps V3. kind of helps with doing an on-click display but everyone's solution was to make one map. I cannot do that. I am overlaying vast amounts of data.
Here is a way you can get that done. (Jump down to the get started part of the script.)
For brevity, I've included a bunch of scripts in one 'file', but you'll want to break them in to individual files.
You may also need to try the html and js in jsbin js bin example, b/c SO may or may not allow the dynamic loading of js.
(function(undefined) {
/**
* #author (#colecmc)
* #method turn collection into an array
* #param {object} collection - NodeList, HTMLCollection, etc. Should have an "item" method and/or a "length" property
*/
ToArray = collection => Array.prototype.slice.call(collection);
/** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/
Observer = (function(undefined) {
/**
* pub sub
*/
'use strict';
var subUid = -1;
return {
topics: {},
subscribe: function(topic, func) {
/**
* #param {string} topic
* #param {function} func
* #returns {string} - a token such as '3'
* #example Observer.subscribe('any-valid-string',function(name,resp){
console.log(resp.prop);
});
*/
if (!Observer.topics[topic]) {
Observer.topics[topic] = [];
}
var token = (++subUid).toString();
Observer.topics[topic].push({
token: token,
func: func
});
return token;
},
publish: function publish(topic, args) {
/**
* #param {string} topic
* #param {object} args
* #returns {boolean} - true if topic is valid, false otherwise
* #example Observer.publish('any-valid-string',{
prop: 'this is a test'
});
*/
if (!Observer.topics[topic]) {
return false;
}
setTimeout(function() {
var subscribers = Observer.topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func(topic, args);
}
}, 0);
return true;
},
unsubscribe: function unsubscribe(token) {
/**
* #param {string} token - value should be saved from the original subscription
* #example Observer.unsubscribe('2');
* #example Observer.unsubscribe(member); - where member is the value returned by Observer.subscribe();
*/
var m,
forEachTopic = function(i) {
if (Observer.topics[m][i].token === token) {
Observer.topics[m].splice(i, 1);
return token;
}
};
for (m in Observer.topics) {
if (Observer.topics.hasOwnProperty(m)) {
Observer.topics[m].forEach(forEachTopic);
}
}
return false;
}
};
}(undefined));
/** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/
SetAttributes = function(el, attrs) {
/**
* #author (#colecmc)
* #method simple for in loop to help with creating elements programmatically
* #param {object} el - HTMLElement attributes are getting added to
* #param {object} attrs - object literal with key/values for desired attributes
* #example SetAttributes(info,{
* 'id' : 'utswFormInfo'
* 'class' : 'my-class-name'
* });
*/
'use strict';
var key;
for (key in attrs) {
if (attrs.hasOwnProperty(key)) {
el.setAttribute(key, attrs[key]);
}
}
return el;
};
/** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/
GetScript = function(url, fullPath) {
/**
* #author (#colecmc)
* #version 1.0.4
* #requires Swlxws.SetAttributes, Swlxws.Observer
* #method dynamically add script tags to the page.
* #param {string} url - relative path and file name - do not include extension
* #param {string} fullPath - absolute path
* #example GetScript('myLocalScript');
* #example GetScript('','https://www.google-analytics.com/analytics.js');
*/
'use strict';
function onLoad(event) {
var result;
if (event.type === 'load') {
result = 1;
} else {
result = -1;
}
Observer.publish('get-script-onload-complete', {
successful: result,
eventData: event
});
}
var JSPATH = '/js/',
/* or where ever you keep js files */
el = document.createElement('script'),
attrs = {
defer: true,
src: null,
type: 'text/javascript'
};
/** look for a string based, protocol agnostic, js file url */
if (typeof fullPath === 'string' && fullPath.indexOf('http') === 0) {
attrs.src = fullPath;
}
/** look for any string with at least 1 character and prefix our root js dir, then append extension */
if (typeof url === 'string' && url.length >= 1) {
attrs.src = JSPATH + url + '.js';
}
SetAttributes(el, attrs);
el.addEventListener('load', onLoad);
el.addEventListener('error', onLoad);
document.body.appendChild(el);
return el;
};
/** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/
/**
* Get Started
*/
function onClick(event) {
GetScript('', event.target.dataset.namespaceUrl);
}
Observer.subscribe('get-script-onload-complete', function(name, resp) {
/** check to make resp is what you expect, ie: the correct script loaded */
/** then it is safe to use */
});
ToArray(document.querySelectorAll('.load-scripts')).map(script => script.addEventListener('click', onClick, false));
}(undefined));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>How to include js files in header of wordpress pages that are activated on-click</title>
</head>
<body>
Load Google Analytics
</body>
</html>
You can use the function wp_enqueue_script() to load the necessary JS files on only the templates you want.
As for your large data set, I recommend that you cache it in an external .json file and use wp_enqueue_script() to load it only when necessary.
Well if the onclick event suggestion is pretty much what you want and you are just concerned about the large amount of data. Then there are a few ways to tackle it. I am not sure if the dataset is a js file or php/json files but i came across a similar issue on one of my projects, dont remember properly but i was doing something with maxmind's ip/location data set.
So i just splitted the large file into 3 smaller ones. Then i looped through each of the file and if the stuff that i was looking for was found in the file then i just breaked out. And definitely as Brian suggested caching and using a CDN would help a lot.

Try to display calendar list from Google API using Java Script

I have some troubles to display list of accesible calendar from Google Calendar via Google API. I use JavaScript and AJAX.
What methods do I need to use?
I found only event`s related methods, but not for display description of calendar.
Thank you!
To get a basic working model you can follow the quickstart example on the calendar API site
The example has a function called listUpcomingEvents() to get events on the "primary" calendar. To get the list of calendars use the following method:
function listCalendars()
{
var request = gapi.client.calendar.calendarList.list();
request.execute(function(resp){
var calendars = resp.items;
console.log(calendars);
});
}
Here's some code I just wrote:
kb.loadAsync('https://apis.google.com/js/client.js', 'onload', 'gapi').then(gapi => {
gapi.auth.authorize({
client_id: __GOOGLE_CALENDAR_API_KEY__,
scope: 'https://www.googleapis.com/auth/calendar',
immediate: true,
}, authResult => {
if(authResult && !authResult.error) {
gapi.client.load('calendar','v3', () => {
gapi.client.calendar.calendarList.list({
maxResults: 250,
minAccessRole: 'writer',
}).execute(calendarListResponse => {
let calendars = calendarListResponse.items;
console.log(calendars.map(cal => cal.summary));
});
});
} else {
console.log('unauthorized');
}
});
});
kb.loadAsync is a helper function I wrote; looks like this:
/**
* Helps load Google APIs asynchronously.
*
* #param {string} source
* #param {string} callbackParam
* #param {string=} globalName
* #returns {Promise}
*/
export function loadAsync(source, callbackParam, globalName) {
return new Promise((resolve,reject) => {
let callbackFunc = Math.random().toString(36);
window[callbackFunc] = () => {
resolve(window[globalName]);
delete window[callbackFunc];
};
let sep = source.includes('?') ? '&' : '?';
$script(`${source}${sep}${encodeURIComponent(callbackParam)}=${encodeURIComponent(callbackFunc)}`);
});
}
It uses scriptjs. Unfortunately scriptjs' callback fires too early -- Google loads some more junk after client.js has downloaded, so it isn't quite ready to run even after it's "ready"! You have to use Google's onload parameter.
You don't need all those dependencies if you just to use a bunch of <script> tags, but I prefer me some async functions.

Categories

Resources