Select/isolate in multimodel approach - autodesk-forge

In API reference described methods to select/isolate objects (in condition that only one model is loaded in viewer):
- select(dbids,selectionType)
- isolate(node)/isolateById(dbids) // that is the difference?
I know select analog for multimodel:
viewer.impl.selector.setSelection([objectIds], model);
Questions are:
Is isolate analog for multimodel mode exists?
How can I select/isolate two objects from diffrenent models at once?

In the recent version of the API the viewer.impl.visibilityManager is returning a MultiModelVisibilityManager, so you can pass a model as second argument:
MultiModelVisibilityManager.prototype.isolate = function (node, model)
Take a look in viewer3D.js (L#17825) to see available methods on that object.
As far as I know there is no way to select two objects from different models in a single call, you would just issue one select call for each model passing respective ids. I don't see a problem with that.
Hope that helps.

For the isolate, you can do something like this(borrowed from the Viewer3D.js):
// Get selected elements from each loaded models
var selection = this.viewer.getAggregateSelection();
var allModels = this.viewer.impl.modelQueue().getModels().concat(); // shallow copy
// Isolate selected nodes.
selection.forEach(function(singleRes){
singleRes.model.visibilityManager.isolate(singleRes.selection);
var indx = allModels.indexOf(singleRes.model);
if (indx >= 0) {
allModels.splice(indx, 1);
}
});
// Hide nodes from all other models
while (allModels.length) {
allModels.pop().visibilityManager.setAllVisibility(false);
}
this.viewer.clearSelection();
For the select, you need to pass corresponding model and dbIds to the viewer.impl.selector.setSelection([dbIds], model); and call setSelection for each set, such as below. It cannot be archived at once.
var selSet = [
{
selection: [1234, 5621],
model: model1
},
{
selection: [12, 758],
model: model2
},
];
selSet.forEach(funciton(sel) {
viewer.impl.selector.setSelection(sel.selection, sel.model);
});

Related

How can I get access to multiple values of nested JSON object?

I try to access to my data json file:
[{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}
This is my approach:
data[0].name;
But like this I get only the result:
Animals
But I would need the result:
Animals, Cats
You are accessing only the name property of 0th index of project array.
To access all object at a time you need to loop over the array.
You can use Array.map for this.
var data = [{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}]
var out = data[0].project.map(project => project.name).toString()
console.log(out)
If that's your actual data object, then data[0].name would give you "Maria". If I'm reading this right, though, you want to get all the names from the project array. You can use Array.map to do it fairly easily. Note the use of an ES6 arrow function to quickly and easily take in the object and return its name.
var bigObject = [{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}];
var smallObject = [{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}];
console.log("Getting the names from the full array/data structure: "+bigObject[0].project.map(obj => obj.name))
console.log("Getting the names from just the project array: "+smallObject.map(obj => obj.name))
EDIT: As per your comment on the other answer, you said you needed to use the solution in this function:
"render": function (data, type, row) {if(Array.isArray(data)){return data.name;}}
To achieve this, it looks like you should use my bottom solution of the first snippet like so:
var data = [{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}];
function render(data, type, row){
if(Array.isArray(data)){
return data.map(obj => obj.name);
}
};
console.log("Render returns \""+render(data)+"\" as an array.");

POSTMAN - Save a property value from a JSON response

I am new to both JSON and Postman(as of yesterday).
I'm trying to do something very simple, I've created a GET request which pulls in a list of forms in a JSON response. I want to take this response and get the first "id" token and place it in a variable.
I am using a global variable but would like to use a collection variable if possible. Either way here is what I am doing.
I've tried several things, most recently this:
var jsonData = JSON.parse(responseBody);
postman.setGlobalVariable("id", jsonData.args.id);
As well as this:
pm.test("GetId", function () {
var jsonData = pm.response.json();
pm.globals.set("id", jsonData.id);
});
Response code looks like this:
{
"forms":[
{
"id":"3197239",
"created":"2018-09-18 11:37:39",
"db":"1",
"deleted":"0",
"folder":"151801",
"language":"en",
"name":"Contact Us",
"num_columns":"2",
"submissions":"0",
"submissions_unread":"0",
"updated":"2018-09-18 12:02:13",
"viewkey":"xxxxxx",
"views":"1",
"submissions_today":0,
"url":"https://xxx",
"data_url":"",
"summary_url":"",
"rss_url":"",
"encrypted":false,
"thumbnail_url":null,
"submit_button_title":"Submit Form",
"inactive":false,
"timezone":"US/Eastern",
"permissions":150
},
{
"id":"3197245",
"created":"2018-09-18 11:42:02",
"db":"1",
"deleted":"0",
"folder":"151801",
"language":"en",
"name":"Football Draft",
"num_columns":"1",
"submissions":"0",
"submissions_unread":"0",
"updated":"2018-09-18 12:11:54",
"viewkey":"xxxxxx",
"views":"1",
"submissions_today":0,
"url":"https://xxxxxxxxx",
"data_url":"",
"summary_url":"",
"rss_url":"",
"encrypted":false,
"thumbnail_url":null,
"submit_button_title":"Submit Form",
"inactive":false,
"timezone":"US/Eastern",
"permissions":150
}
]
}
This would get the first id:
pm.globals.set('firstId', _.first(pm.response.json().forms).id)
That would get the first in the array each time so it would set a different variable it that response changed.
The test that you created was nearly there but the reference needed to go down a level into the forms array:
pm.test("GetId", function () {
var jsonData = pm.response.json()
pm.expect(jsonData.forms[0].id).to.equal("3197239")
pm.globals.set("id", jsonData.forms[0].id)
})
The [0]is referencing the first id in the first object within the array. For example [1] would get the second one and so on.
You currently cannot set a collection level variable using the pm.* API - These can only be added manually and referenced using the pm.variables.get('var_name') syntax.
Edit:
In the new versions of the desktop app you can set variables at the Collection level using pm.collectionVariables.set().
Based on the name or any other attribute if you want to set the id as a global variable then this is the way.
for(var i=0; i<jsonData.forms.length; i++)
{
if (jsonData.forms[i].name==="Contact Us")
{
pm.environment.set("id", jsonData.forms[i].id);
}
}

ExtJS 5.0 Forms generated/driven by a store

I would like to create a Form in ExtJS 5.0 completely based on a Store. Every store item represents a "line in the form". A "line" consists three or more form widgets.
Basically this is a search panel, where you define search conditions. Every condition consits of: FieldName selector, an operator selector, and a widget to write/select a condition operand. For example search for people with:
name starting with Joe (FieldName:name, operator:starting with, widget:textfield)
birtday before 1980.01.01. (FieldName:birthday, operator:before, widget:datepicker)
I get the conditions in JSON, and load them in a Store. I would like to dynamically generate the form based on this store, make modifications in the form, and ask the Store for a new JSON with the modifications (new conditions, etc).
I have problems with the first step: simply generate form widgets based on store content.
How can this be done?
I'm going to assume here that the JSON data represents a variety of dynamic data, and you can't simply use a pre-canned control like a grid, or a fixed form.
What you need to do is to make your own container class, which dynamically creates widgets based on the JSON content. You'll have to write this yourself, of course.
One extreme is to make your JSON content in the store be valid arguments to, say, Ext.widget - but that's probably not feasible, or even desirable.
For a more middling position, use the JSON data to determine, based on conditions, what widgets to add.
As a rough outline, you want something like this:
Ext.define('MyFormContainer', {
extend: 'Ext.form.FormPanel',
config: {
// A store or MixedCollection of JSON data objects, keyable by id.
formData: null
},
layout: 'vbox',
initComponent: function() {
this.callParent(arguments);
this.getFormData().each(this.addField, this)
},
addField: function(fieldData) {
var widgetConfig = this.buildWidgetConfig(fieldData);
this.add(widgetConfig);
},
buildWidgetConfig: function(fieldData) {
// The heart of the factory. You need a way to determine what sort of widget to make for
// the field. For the example config, a fieldset with three fields would probably be
// appropriate:
var fieldSet = { xtype: 'fieldset', layout: 'hbox' };
var items = [];
items[0] = { xtype: 'textfield', name: fieldData['FieldName'] };
// this would be a link to a custom widget to handle the operator. Or maybe you could
// just spit out text, if it's not meant to be alterable.
items[1] = { xtype: 'myoperator_' + fieldData['operator'], name: 'operator' };
items[2] = { xtype: fieldData['widget'], name: 'value' }
fieldSet.items = items;
return fieldSet;
}
})
This is a simple and contrived example, but it should (after you fill in the blanks, such as missing requires and the custom operator widgets) render a form based on the JSON data.
(I personally use this approach - with a great deal more sophistication that I can show in a simple example - to generate dynamic forms based on server-supplied form descriptions)

Filtering and rearranging model/content in Ember Controllers

Let's say I have a JSON array of data, something like:
[ {"name":"parijat","age":28},
{"name":"paul","age":28},
{"name":"steven","age"27},
...
]
that is part of my model, and this model is setup like this:
App.UserRoute = Ember.Route.extend({
model:function(){
return App.User.FIXTURES ; // defined above
}
});
I want to get the unique ages from this JSON array and display them in my template, so I reference the computed properties article and read up a little on how to enumerate Ember Enumerables, to eventually get this:
App.UserController = Ember.ArrayController.extend({
ages:function(){
var data = this.get('content');
var ages = data.filter(function(item){
return item.age;
});
}.property('content');
});
Now the above piece of code for controller is not correct but the problem is that it doesn't even go into data.filter() method if I add a console.log statements inside. IMO, it should typically be console logging as many times as there exist a App.Users.FIXTURE. I tried using property('content.#each') which did not work either. Nor did changing this.get('content') to this.get('content.#each') or this.get('content.#each').toArray() {spat an error}.
Not sure what to do here or what I am completely missing.
Filter is used for reducing the number of items, not for mapping.
You can use data.mapBy('age') to get an array of your ages:
ages:function(){
return this.get('content').mapBy('age');
}.property('content.#each')
or in your handlebars function you can just use the each helper:
{{#each item in controller}}
{{item.age}}
{{/each}}

Create "batch" request using ExtJS 4.1 REST Proxy

I've got two model/proxy/stores I'm concerned with Questions and Choices. Both get data from a REST server as JSON. My process currently goes like this:
// load numQuestions records from store.Questions
var qs = Ext.getStore('Question');
//... loadmask, etc.
qs.load({
scope : this,
params : {
limit : numQuestions
},
callback : function() {
this.createQuestionCards(numQuestions);
}
});
Once I have the Questions, I loop through and fetch the Choices that are relevant to each Question like:
for ( i = 0; i < numQuestions; i++) {
// ... misc ...
Assessor.questionChoices[i] = qs.getAt(i).choices();
// ...misc...
},
This works well, except that it makes an XMLHTTPRequest for every loop iteration. With minimum response times in the 0.15 sec area, that is fine for N < ~40. Once the numbers get to 200, which should be a common use case, the delay is nasty.
How do I get ExtJS to "batch" the requests and send them after the loop body? For example:
var choiceBatch = qs.createBatch();
for ( i = 0; i < numQuestions; i++) {
// ... misc ...
Assessor.questionChoices[i] = choiceBatch.getAt(i).choices();
// ...misc...
};
choiceBatch.execute();
The Ext.data.proxy.Rest has a config option batchActions and since it's basically an AjaxProxy with different methods it will probably work in the same way as the AjaxProxy.
Since I am not getting clear answer about restful batch with multipart...
testing on my own with batchActions=true in Ext.data.proxy.Rest v4.2.1 result that batch is only within the same store and HTTP method. (batchActions default to false for the REST)
That means if there is 200 post & 1 delete and you call store.sync(), it will batch into 2 request, the POST request body will be wrapped with an array of records instead of single record.
I am looking for if it can batch all stores with all GET, POST, PUT and DELETE by using multipart/mixed but the result is negative. (check out OData Batch Processing)
Regarding the OP, what you looking for is the model associations. Once you create Questions and Choices Ext model and let the server respond with nested json data (So the Questions contain the child Choices embedded in a request) Ext will create question record along with question.choices() child store automatically.