breeze.js how do I share metadata between 2 entity managers - javascript

I have 2 entity managers:
var mgr1 = new breeze.EntityManager('api/app');
var mgr2 = new breeze.EntityManager('api/app');
Right now I am getting the metadata for each one separately, although the metadata is exactly the same. I am calling the fetch method explicitly to control the timing of when the metadata is loaded.
mgr1.fetchMetadata();
mgr2.fetchMetadata();
I've read that I can share the metadata between the 2 managers but I have not found an example. From what I've read, I think I can specify the metadata in the constructor of the 2nd manager that references the 1st manager's metadata, but not sure what that would look like. So my code would look something like this:
var mgr1 = new breeze.EntityManager('api/app');
mgr1.fetchMetadata();
var mgr2 = new breeze.EntityManager({ serviceName: 'api/app', metadata: WHAT_GOES_HERE});
I know I will also have to sequnece this with promises so the 2nd manager isn't constructed before the 1st managers has it's metadata loaded.
Am I on the right path with this? My goal is to eliminate the extra bandwidth to load the metadata for the 2nd manager. thanks

You don't actually have to fetch the metadata to share the same MetadataStore. The following two statements are a pretty crisp approach:
var em1 = new breeze.EntityManager('api/app');
var em2 = em1.createEmptyCopy();
I'm not trying to be clever. My point is that a MetadataStore, which is a container of metadata, is available immediately after EntityManager creation and is well defined prior to holding any metadata whatsoever.
The createEmptyCopy() method "clones" the manager without copying its entity cache contents. The copied attributes include the manager's MetadataStore and its DataService.
Because the managers share the same MetadataStore, fetching metadata with either manager will do the trick.
Check out the Breeze API documentation for EntityManager and MetadataStore.

I have never used breeze.js before, but from what I gather from the documentation (http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html), something like this should work:
var mgr1 = new breeze.EntityManager('api/app');
mgr1.fetchMetadata();
var mgr2 = new breeze.EntityManager({
serviceName: 'api/app',
metadataStore: mgr1.metadataStore
});
Of course mgr2 should be set up after the mgr1.fetchMetadata promise is fulfilled, as you already say in your question.

Related

How to get Model object metadata properties in Javascript AutoDesk

I am working with AutoDesk Forge Viewer (2D) in Javascript with Offline svf file.
I have converted the .dwg file to svf file.
How can I get Model Object Metadata properties in Javascript like we get using the api "https://developer.api.autodesk.com/modelderivative/v2/designdata/{urn}/metadata/{guid}/properties" ?
I tried using viewer.model.getProperties(dbId,function,funtion), but this only gives me details of particular to that dbId but i want the list of properties.
Please help me with this.
firstly, the other blog talks about how Model Derivative extracts properties. In theory, if you get 'aka json (json.gz)' or 'sqlLite (sdb/db)', you would be able to extract yourself by other tools.
How properties.db is used in Forge Viewer?.
I believe you have known http://extract.autodesk.io/ as you said you have downloaded SVF. http://extract.autodesk.io/ provides you with the logic to download translated data, including json.gz and sqlLite db.
While if you prefer to dump all properties within browser by Forge Viewer, the only way I can think is as below:
function getAllDbIds(viewer) {
var instanceTree = viewer.model.getData().instanceTree;
var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
return allDbIdsStr.map(function(id) { return parseInt(id)});
}
var AllDbIds = getAllDbIds(myViewer);
myViewer.model.getBulkProperties(AllDbIds, null,
function(elements){
console.log(elements);//this includes all properties of a node.
})
Actually, I combined two blogs:
https://forge.autodesk.com/cloud_and_mobile/2016/10/get-all-database-ids-in-the-model.html
https://forge.autodesk.com/blog/getbulkproperties-method

Backbone Sub-Collections & Resources

I'm trying to figure out a Collection/Model system that can handle retrieving
data given the context it's asked from, for example:
Available "root" resources:
/api/accounts
/api/datacenters
/api/networks
/api/servers
/api/volumes
Available "sub" resources:
/api/accounts/:id
/api/accounts/:id/datacenters
/api/accounts/:id/datacenters/:id/networks
/api/accounts/:id/datacenters/:id/networks/:id/servers
/api/accounts/:id/datacenters/:id/networks/:id/servers/:id/volumes
/api/accounts/:id/networks
/api/accounts/:id/networks/:id/servers
/api/accounts/:id/networks/:id/servers/:id/volumes
/api/accounts/:id/servers
/api/accounts/:id/servers/:id/volumes
/api/accounts/:id/volumes
Then, given the Collection/Model system, I would be able to do things like:
// get the first account
var account = AccountCollection.fetch().first()
// get only the datacenters associated to that account
account.get('datacenters')
// get only the servers associated to the first datacenter's first network
account.get('datacenters').first().get('networks').first().get('servers')
Not sure if that makes sense, so let me know if I need to clarify anything.
The biggest kicker as to why I want to be able to do this, is that if the
request being made (ie account.get('datacenters').first().get('networks'))
hasn't be made (the networks of that datacenter aren't loaded on the client)
that it is made then (or can be fetch()d perhaps?)
Any help you can give would be appreciated!
You can pass options to fetch that will be translated to querystring params.
For example:
// get the first account
var account = AccountCollection.fetch({data: {pagesize: 1, sort: "date_desc"}});
Would translate to:
/api/accounts?pagesize=1&sort=date_desc
It is not quite a fluent DSL but it is expressive and efficient since it only transmits the objects requested rather than filtering post fetch.
Edit:
You can lazy load your sub collections and use the same fetch params technique to filter down your list by query string criteria:
var Account = Backbone.Model.extend({
initialize: function() {
this.datacenters = new Datacenters;
this.datacenters.url = "/api/account/" + this.id + '/datacenters';
}
});
Then from an account instance:
account.datacenters.fetch({data: {...}});
Backbone docs on fetching nested models and collections

Databinding to Windows 8 ListView

I'm having massive problems with databinding to a ListView in a Windows 8 app using Javascript.
Inside the "activated" event on default.js I have written some code to get some data from a web service and push it into an array. This bit works OK and the array is populated.
The problem I have is that the app won't recognise the data. I have this code in a page called inspections.html:
data-win-options="{itemTemplate: select('#imageTextListCollectionTemplate'),
itemDataSource: dataList.dataSource,
layout: {type: WinJS.UI.ListLayout}}
and then in the "activated" event I declare:
var dataList = new Array();
and push the data from the web service into this array. But at runtime I get an error that says something along the lines of "can't find dataSource on undefined dataList".
I've done some of the examples on the MS website and in one of them it creates a dummy dataset and references it from a namespace. I kinda think that what I'm missing here is a namespace too but I don't know what the namespace for default.js is. Or maybe I'm wrong and it's something totally different.
Please help - this is so fundamental (and should be easy) but I can't get my head around it.
Do you want to create datalist in HTML or javascript?
It seems you want to create it from JavaScript. Assuming that you have already pushed your data into array from your webservice, you only need to call:
var dataList = new WinJS.Binding.List(array);
now accessing dataList.dataSource is perfectly valid.
Also, to create the datalist you don't always need an array. You could probably start with an empty list and then keep inserting data directly into the data list from web services, like:
var dataList = new WinJS.Binding.List([]);
dataList.push(value1);
dataList.push(value2);
...
Hope it helps. Let me know if you have any more questions.
If you are getting troubled by assigning datasource in HTML side
Prefer js side like
var list = new WinJS.Binding.List(array here);
listView.itemDataSource = list.dataSource;
by using this you can easily go through the data which you are binding to ListView.

How go I get csv data into netsuite?

I've got an update to my question.
What I really wanted to know was this:
How do I get csv data into netsuite?
Well, it seems I use the csv import tool to create a mapping and use this call to import the csv nlapiSubmitCSVImport(nlobjCSVImport).
Now my question is: How do I iterate through the object?!
That gets me half way - I get the csv data but I can't seem to find out how I iterate through it in order to manipulate the date. This is, of course, the whole point of a scheduled script.
This is really driving me mad.
#Robert H
I can think of a million reasons why you'd want to import data from a CSV. Billing, for instance. Various reports on data any company keeps and I wouldn't want to keep this in the file cabinet nor would I really want to keep the file at all. I just want the data. I want to manipulate it and I want to enter it.
Solution Steps:
To upload a CSV file we have to use a Suitelet script.
(Note: file - This field type is available only for Suitelets and will appear on the main tab of the Suitelet page. Setting the field type to file adds a file upload widget to the page.)
var fileField = form.addField('custpage_file', 'file', 'Select CSV File');
var id = nlapiSubmitFile(file);
Let's prepare to call a Restlet script and pass the file id to it.
var recordObj = new Object();
recordObj.fileId = fileId;
// Format input for Restlets for the JSON content type
var recordText = JSON.stringify(recordObj);//stringifying JSON
// Setting up the URL of the Restlet
var url = 'https://rest.na1.netsuite.com/app/site/hosting/restlet.nl?script=108&deploy=1';
// Setting up the headers for passing the credentials
var headers = new Array();
headers['Content-Type'] = 'application/json';
headers['Authorization'] = 'NLAuth nlauth_email=amit.kumar2#mindfiresolutions.com, nlauth_signature=*password*, nlauth_account=TSTDRV****, nlauth_role=3';
(Note: nlapiCreateCSVImport: This API is only supported for bundle installation scripts, scheduled scripts, and RESTlets)
Let's call the Restlet using nlapiRequestURL:
// Calling Restlet
var output = nlapiRequestURL(url, recordText, headers, null, "POST");
Create a mapping using Import CSV records available at Setup > Import/Export > Import CSV records.
Inside the Restlet script Fetch the file id from the Restlet parameter. Use nlapiCreateCSVImport() API and set its mapping with mapping id created in step 3. Set the CSV file using the setPrimaryFile() function.
var primaryFile = nlapiLoadFile(datain.fileId);
var job = nlapiCreateCSVImport();
job.setMapping(mappingFileId); // Set the mapping
// Set File
job.setPrimaryFile(primaryFile.getValue()); // Fetches the content of the file and sets it.
Submit using nlapiSubmitCSVImport().
nlapiSubmitCSVImport(job); // We are done
There is another way we can get around this although neither preferable nor would I suggest. (As it consumes a lot of API's if you have a large number of records in your CSV file.)
Let's say that we don't want to use the nlapiCreateCSVImport API, so let's continue from the step 4.
Just fetch the file Id as we did earlier, load the file, and get its contents.
var fileContent = primaryFile.getValue();
Split the lines of the file, then subsequently split the words and store the values into separate arrays.
var splitLine = fileContent.split("\n"); // Splitting the file on the basis of lines.
for (var lines = 1,count=0; lines < splitLine.length; lines++)
{
var words = (splitLine[lines]).split(","); // words stores all the words on a line
for (var word = 0; word < words.length; word++)
{
nlapiLogExecution("DEBUG", "Words:",words[word]);
}
}
Note: Make sure you don't have an additional blank line in your CSV file.
Finally create the record and set field values from the array that we created above.
var myRec = nlapiCreateRecord('cashsale'); // Here you create the record of your choice
myRec.setFieldValue('entity', arrCustomerId[i]); // For example, arrCustomerId is an array of customer ID.
var submitRec = nlapiSubmitRecord(myRec); // and we are done
fellow NetSuite user here, I've been using SuiteScripts for a while now but never saw nlobjCSVImport object nor nlapiSubmitCSVImport .. I looked in the documentation, it shows, but there is no page describing the details, care to share where you got the doc from?
With the doc for the CSVImport object I might be able to provide some more help.
P.S. I tried posting this message as a comment but the "Add comment" link didn't show up for some reason. Still new to SOF
CSV to JSON:
convert csv file to json object datatable
https://code.google.com/p/jquery-csv/
If you know the structure of the CSV file, just do a for loop and map the fields to the corresponding nlapiSetValue.
Should be pretty straightforward.

ExtJS 4 Set Reader

I have a JSON that used by other parts in application a few times.
To avoid unneeded calls, I want to fetch it ones, and than only use it
where it needs.
the issue is, that JSON cantains a different sections for different parts,
thats why I need to use root property.
What I need:
- Proxy that will fetch it ones (One for all)
- Reader for each part, 'cause they use different root
- Store for different parts
Proxy:
var myProxy = new Ext.data.proxy.Ajax({
url: "static/data/myData.json"
});
var operation = new Ext.data.Operation({
action: "read"
});
myProxy.read(operation);
Some Part:
// try to create custom reader with appropriate root
var reader = new Ext.data.reader.Json({
root: "table1"
});
// set reader to proxy
myProxy.setReader(reader);
// create store
Ext.create("Ext.data.Store", {
storeId: "MyStore",
model: "MyModel",
autoLoad: true
});
// set proxy to store
Ext.data.StoreManager.lookup("MyStore").setProxy(proxy);
Of course, this doesn't work. How I have to do it?
You'd be better off using a AJAX fetch to get the JSON, caching it in some variable and then using your store's loadData method to fill each store as needed. loadData lets you manually add records without going to the remote data source. That'll give you tighter control without having to deal with the proxies; just the readers and stores.

Categories

Resources