I'm studying the OpenSceneGraph these days:
// Assumes the Cessna's root node is a group node.
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg");
osg::Group* convModel1 = model->asGroup(); // OK!
osg::Geode* convModel2 = model->asGeode(); // Returns NULL?
Why model->asGeode(); Returns NULL?
If you look at cessna.osg in a text editor:
Group {
UniqueID Group_0
DataVariance STATIC
cullingActive TRUE
num_children 1
Geode {
DataVariance DYNAMIC
name "cessna.osg"
cullingActive TRUE
num_drawables 1
Geometry {
you'll see that the top-level entity is a Group, not a Geode. You need to getChild() on the Node that comes back from readNodeFile, and then you should be able to asGeode() that.
Related
I have a list of values each having another KEY value corresponding to it, when i present this list to user, user has to select a value and agent has to call an external api with selected value's KEY. how can i achieve this in dialogflow?
I tried to send the entire key value pair in the context and access it in the next intent but for some reason when i set a list(array) to context parameters dialogflow simply ignoring the fulfillment response.
What is happening here and is there any good way to achieve this? I am trying to develop a food ordering chatbot where the category of items in menu is presented and list items in that menu will fetched when user selects a category, this menu is not static thats why i am using api calls to get the dynamic menu.
function newOrder(agent)
{
var categories = []
var cat_parameters = {}
var catarray = []
const conv = agent.conv();
//conv.ask('sure, select a category to order');
agent.add('select a category to order');
return getAllCategories().then((result)=>{
for(let i=0; i< result.restuarantMenuList.length; i++)
{
try{
var name = result.restuarantMenuList[i].Name;
var catid = result.restuarantMenuList[i].Id;
categories.push(name)
//categories.name = catid
cat_parameters['id'] = catid;
cat_parameters['name'] = name
catarray.push(cat_parameters)
}catch(ex)
{
agent.add('trouble getting the list please try again later')
}
}
agent.context.set({
name: 'categorynames',
lifespan: 5,
parameters: catarray, // if i omit this line, the reponse is the fultillment response with categories names, if i keep this line the reponse is fetching from default static console one.
})
return agent.add('\n'+categories.toString())
})
function selectedCategory(agent)
{
//agent.add('category items should be fetched and displayed here');
var cat = agent.parameters.category
const categories = agent.context.get('categorynames')
const cat_ob = categories.parameters.cat_parameters
// use the key in the catarray with the parameter cat to call the external API
agent.add('you have selected '+ cat );
}
}
The primary issue is that the context parameters must be an object, it cannot be an array.
So when you save it, you can do something like
parameters: {
"cat_parameters": catarray
}
and when you deal with it when you get the reply, you can get the array back with
let catarray = categories.parameters.cat_parameters;
(There are some other syntax and scoping issues with your code, but this seems like it is the data availability issue you're having.)
model
asset Route identified by route_id {
o String route_id
o String rider_id
o String parcel_id
}
transaction assignParcelToRider {
o String rider_id
o String parcel_id
}
logic.js
var assetRegistry;
var id = assignValue.rider_id;
return getAssetRegistry('org.rytle.Route').then(function(ar) {
assetRegistry = ar;
return assetRegistry.get(id);
}).then(function(asset) {
asset.parcel_id = assignValue.parcel_id;
return assetRegistry.update(asset);
});
Here I want to find the rider_id and update parcel_id there. But here its not finding the rider_id.
The main thing is you need to get the asset, by the asset identifier when using .get() and rider_id is not that, in your model.
Also - may need more info - but it all rests on id getting a value from assignValue.rider_id and I can't tell how that was defined / asserted and whether it is within scope. I can see that id however, should be in scope for your function below - but using the correct identifier for an asset, this should work (as an example):
return getAssetRegistry('org.rytle.Route').then(function(ar) {
return ar.get(route_id) // or whatever you've assigned it to or txnobject.route.getIdentifier()); // ie you must get the asset by identifier
}).then(function(asset) {
asset.parcel_id = id;
return ar.update(asset);
});
and so on;
ps you can check out sample-networks for some examples (eg under 'test' directory) - note these now use async / await functions (instead of 'promises' shown above) which came in with Node 8 (and is far easier to write than using promises FYI)
I have a userevent script to change the Field in Contract record from PO record. The Script is running fine. But whenever I edit a contract record and try to submit it : It throws the error "Another user has updated this record since you began editing it. Please close the record and open it again to make your changes".
May I know the reason behind this ?
/*---------------------------------------------------------------------------------------------------------------
Description : Whenever the PO vendor is changed(due to Split vendor) that should replace the same in Contract page record automatically.
Script type : User Event Script
Script id : customscript452
Version : 1.0
Applied to : Contract
----------------------------------------------------------------------------------------------------------------*/
function srchfield()
{
var stRecordid = nlapiGetRecordId(); //returns the contract id
if(stRecordid== undefined || stRecordid== null || stRecordid==' ')
{
}
else
{
var stRecordtype = nlapiGetRecordType(); //returns the contract record type = jobs
var stRecord = nlapiLoadRecord(nlapiGetRecordType(), stRecordid);
nlapiLogExecution('debug','Load Object',stRecord);
var stContractID = stRecord.getFieldValue('entityid'); //returns the value of the field contractid whose fieldid is = entityid
nlapiLogExecution('debug','stContractID',stContractID);
var stCompanyName = stRecord.getFieldValue('companyname'); //returns the value of the field company name whose fieldid is = companyname
nlapiLogExecution('debug','stCompanyName',stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
var arrFilters = new Array(); // This is Array Filters all the Purchase Order Record Search
arrFilters.push(new nlobjSearchFilter('type', null, 'anyof',
[
'PurchOrd'
]));
arrFilters.push(new nlobjSearchFilter('mainline', null, 'is', 'T')); //This is to exclude line level results
arrFilters.push(new nlobjSearchFilter('custbodycontract', null, 'is', stRecordid)); //This is Filters in Contracts Search
var arrColumns = new Array();
arrColumns.push(new nlobjSearchColumn('entity')); //This is Search Column Field in Records
var arrSearchresults = nlapiSearchRecord('purchaseorder', null, arrFilters, arrColumns); //This is Filters in Search Result Purchase Order
if(arrSearchresults== undefined || arrSearchresults== null || arrSearchresults==' ')
{
}
else
{
var length = arrSearchresults.length;
}
if(length== undefined || length== null || length==' ')
{
}
else
{
for (var i = 0; arrSearchresults != null && i < arrSearchresults.length; i++)
{
var objResult = arrSearchresults[i];
var stRecId = objResult.getId();
var stRecType = objResult.getRecordType();
var stCntrctName = objResult.getValue('entity'); //This is Value are Get Purchase Order Records and Field for Vendor = entity
}
}
//var record = nlapiLoadRecord(nlapiGetRecordType(), stRecordid, stCntrctName);
if (stCntrctName =='custentityranking_vendor_name')
{
}
else
{
var stChangeName = stRecord.setFieldValue('custentityranking_vendor_name', stCntrctName); //This is Value are the Set in Main Vendor Field = custentityranking_vendor_name
nlapiSubmitRecord(stRecord, null, null); // Submit the Field Value in Record Type
}
}
}
The User Event script executes as the Contract record is being saved to the database. At the same time, you are loading a second copy of the record from the database and trying to submit the copy as well. This is causing the error you're seeing.
You fix this by just using nlapiSetFieldValue to set the appropriate field on the Contract.
I might also recommend getting more familiar with JavaScript by going through the JavaScript Guide over at MDN. In particular, take a look at the Boolean description so that you know how JavaScript evaluates Boolean expressions. This will help you greatly reduce the amount of code you've written here, as many of your conditionals are unnecessary.
What userevent do you have? It is happening depending on what type of user event and API you are using. Looking at your code, you are trying to load contract record that is already updated at the database. So you might consider below to address your issue. Hope, it helps.
If it is a before submit, you don't need to load the record where the script is deployed.
Just use nlapiGet* and nlapiSet* to get and set values. You also don't need to use nlapiSubmitRecord to reflect the change. With before submit, it executes before the record is being saved to the database. So your changes will still be reflected.
Then if it is after submit, it will be executed after the record has been saved to the database, Thus you might use the following API depending on your needs. Actually, this is the best practice to make sure the solution .
nlapiGetNewRecord - only use this if the script only needs to retrieve info from header and sublists. And nothing to set.
nlapiLookupField - use this if the script only needs to get value/s at the header and nothing from the line.
nlapiSubmitField - the script don't need to load and submit record if the changes only on header. Just use this API.
nlapiLoadRecord and nlapiSubmitRecord- use the former if the script will have changes at the line and then use the latter api to commit it on the database.
Being a user event script code, The code you showed is very not good considering performance.
Here is the sample you can merge
var stRecordid = nlapiGetRecordId(); //returns the contract id
// Every record has an internal id associated with it. No need to add condition explicitly to check if its null
var stRecordtype = nlapiGetRecordType();
var fields = ['entityid','companyname'];
var columns = nlapiLookupField(stRecordtype, stRecordid, fields);
var stContractID = columns.entityid;
var stCompanyName = columns.companyname;
nlapiLogExecution('debug','stContractID/stCompanyName',stContractID+'/'+stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
//
//your code of search
//you can improve that code also by using nlapilook up
nlapiSubmitField(stRecordtype, stRecordid, 'custentityranking_vendor_name', 'name to be updated');
It's difficult to explain the case by words, let me give an example:
var myObj = {
'name': 'Umut',
'age' : 34
};
var prop = 'name';
var value = 'Onur';
myObj[name] = value; // This does not work
eval('myObj.' + name) = value; //Bad coding ;)
How can I set a variable property with variable value in a JavaScript object?
myObj[prop] = value;
That should work. You mixed up the name of the variable and its value. But indexing an object with strings to get at its properties works fine in JavaScript.
myObj.name=value
or
myObj['name']=value (Quotes are required)
Both of these are interchangeable.
Edit: I'm guessing you meant myObj[prop] = value, instead of myObj[name] = value. Second syntax works fine: http://jsfiddle.net/waitinforatrain/dNjvb/1/
You can get the property the same way as you set it.
foo = {
bar: "value"
}
You set the value
foo["bar"] = "baz";
To get the value
foo["bar"]
will return "baz".
You could also create something that would be similar to a value object (vo);
SomeModelClassNameVO.js;
function SomeModelClassNameVO(name,id) {
this.name = name;
this.id = id;
}
Than you can just do;
var someModelClassNameVO = new someModelClassNameVO('name',1);
console.log(someModelClassNameVO.name);
simple as this
myObj.name = value;
When you create an object myObj as you have, think of it more like a dictionary. In this case, it has two keys, name, and age.
You can access these dictionaries in two ways:
Like an array (e.g. myObj[name]); or
Like a property (e.g. myObj.name); do note that some properties are reserved, so the first method is preferred.
You should be able to access it as a property without any problems. However, to access it as an array, you'll need to treat the key like a string.
myObj["name"]
Otherwise, javascript will assume that name is a variable, and since you haven't created a variable called name, it won't be able to access the key you're expecting.
You could do the following:
var currentObj = {
name: 'Umut',
age : 34
};
var newValues = {
name: 'Onur',
}
Option 1:
currentObj = Object.assign(currentObj, newValues);
Option 2:
currentObj = {...currentObj, ...newValues};
Option 3:
Object.keys(newValues).forEach(key => {
currentObj[key] = newValues[key];
});
Basically my requirement is to create a matrix item through the script. I'm wondering if is there any way to create a matrix item through Restlet or any Workflow. I succeeded creating the parent item with some specific attributes but it seems after submitting the record there is no child items getting created.
Bellow is the code snippet what I'm using right now.
var record= nlapiCreateRecord('serviceitem');
record.setFieldValue('name', 'Matrix Parent Record');
record.setFieldValue('matrixtype', 'PARENT');
record.setFieldValue('custitem_matrix_op1', '2');
record.setFieldValue('custitem_matrix_op2', '3');
var id=nlapiSubmitRecord(record);
Any help or suggestions would be appreciated.
Thank You.
Little example:
var parent = nlapiCreateRecord('noninventoryitem');
parent.setFieldValue('matrixtype', 'PARENT');
parent.setFieldValue('itemid', 'zzz ttt');
parent.setFieldValue('subsidiary', 2);// internalid for subs.
parent.setFieldValue('taxschedule', 4);// internalid for N/A in my account
parent.setFieldValues('itemoptions', ['CUSTCOL_LLL_EVENTLOCATION_OPT']);//option to be shown at PDP
parent.setFieldValue('custitem_event_location', 11);// particular option id (see in your list)
var parentid = nlapiSubmitRecord(parent);
var child = nlapiCreateRecord('noninventoryitem');
child.setFieldValue('matrixtype', 'CHILD');
child.setFieldValue('parent', parentid);
child.setFieldValue('itemid', 'zzz ttt child');
child.setFieldValue('taxschedule', 4);// internalid for N/A in my account
child.setFieldValues('itemoptions', ['CUSTCOL_LLL_EVENTLOCATION_OPT']);// same as in parent record
child.setFieldValue('matrixoptioncustitem_event_location', 11);// same as in parent record
var childid = nlapiSubmitRecord(child );
It will create a matrix with one child item.
Do not forget to set up additional fields like price and "display in web store" (isonline field).
After creating the parent item, you need to create child item as well,In the child item set the parent item internal ID & submit the record.
but here there is a drawback. because of static sub list, am not able to append the child items to parent in the Matrix sub list.
Using Suite Talk you could do something like this
/** Create Sweaters as matrix items.
* First create the parent - no matrix properties except "Matrix Type" is Parent
* Second create the matrix children with a combination of sizes and colors.
* This can be done in a single addList (as shown).
*/
//Define mrr method
public static RecordRef mrr(String internalId)
{
RecordRef toRet = new RecordRef();
toRet.setInternalId(internalId);
return toRet;
}
// Define makeListOrRecordRef method
public static ListOrRecordRef makeListOrRecordRef(String sTypeId, String internalId, String sName)
{
ListOrRecordRef toRet = new ListOrRecordRef();
toRet.setInternalId(internalId);
toRet.setName(sName);
toRet.setTypeId(sTypeId);
return toRet;
}
public void testMatrixSample() throws Exception
{
// Color is a Custom List of TypeId/RecType 1 that has already been created. 1,2,3 represent the
// internalIds of Red, Green, Blue
ListOrRecordRef[] colorArray = new
ListOrRecordRef[] {makeListOrRecordRef("1","1","Red"), makeListOrRecordRef("1","2","Green"),
makeListOrRecordRef("1","3","Blue")}; // Representing red, green and blue
// Size is a CustomList of TypeId/RecType 2 that has already been created
ListOrRecordRef[] sizeArray = new ListOrRecordRef[]{makeListOrRecordRef("2","2","Large"),makeListOrRecordRef("2","3","Small")};
//Representing large and small
InventoryItem[] toSubmit = new InventoryItem[1+colorArray.length*sizeArray.length];
toSubmit[0] = new InventoryItem();
toSubmit[0].setExternalId("parentSweater");
toSubmit[0].setItemId("sweater");
toSubmit[0].setMatrixType(ItemMatrixType._parent);
// set other fields on the Parent
for (int i=0;i<colorArray.length*sizeArray.length;i++)
{
toSubmit[i+1] = new InventoryItem();
toSubmit[i+1].setMatrixType(ItemMatrixType._child);
// mrr Creates a recordRef given an internal and externalId, the latter of which we specify.
// This makes it so we can submit all the records at once
toSubmit[i+1].setParent(mrr((String)null,"parentSweater"));
// "sweater-large-red","sweater-large-green"...
toSubmit[i+1].setItemId("sweater-"+colorArray[i%3].getName() + "-" +
sizeArray[i % 2].getName());
// set externalId so it's easier to find later
toSubmit[i+1].setExternalId(toSubmit[i+1].getItemId());
// CUSTITEM_COLOR,SIZE are the names of the Item Custom Fields, applied to
//InventoryItem that were setup as a Matrix types.
SelectCustomFieldRef colorRef = new SelectCustomFieldRef();
colorRef.setInternalId("CUSTITEM_COLOR");
colorRef.setValue(colorArray[i%3]);
SelectCustomFieldRef sizeRef = new SelectCustomFieldRef();
sizeRef.setInternalId("CUSTITEM_SIZE");
sizeRef.setValue(sizeArray[i%2]);
toSubmit[i+1].setMatrixOptionList(new MatrixOptionList(new
SelectCustomFieldRef[]{colorRef,sizeRef}));
// Set other matrix item child files
//....
}
WriteResponseList wr = c.getPort().addList(toSubmit);
}