I´ve downloaded the Forge Design Automation sample from the following link:
https://learnforge.autodesk.io/#/tutorials/modifymodels
But the downloable code example is not working fine. When any async method who involves the DesignAutomation API is called I get -> Value cannot be null. (Parameter 'ForgeConfiguration.ClientId'). So, I would like to know how it works and how I can set the ClientId in the ForgeConfiguration class or else if I making something else wrong. I attach a fragment of code where I get the error.
[HttpGet]
[Route("api/forge/designautomation/engines")]
public async Task<List<string>> GetAvailableEngines()
{
List<string> allEngines = new List<string>();
try
{
dynamic oauth = await OAuthController.GetInternalAsync();
// define Engines API
string paginationToken = null;
while (true)
{
Page<string> engines = await _designAutomation.GetEnginesAsync(paginationToken);
allEngines.AddRange(engines.Data);
if (engines.PaginationToken == null)
break;
paginationToken = engines.PaginationToken;
}
allEngines.Sort();
}
catch (Exception error) {
throw error;
}
return allEngines; // return list of engines
}
And the call of the method:
function prepareLists() {
list('engines', 'api/forge/designautomation/engines');
}
function list(control, endpoint) {
$('#' + control).find('option').remove().end();
jQuery.ajax({
url: endpoint,
success: function (list) {
if (list.length === 0)
$('#' + control).append($('<option>', { disabled: true, text: 'Nothing found' }));
else
list.forEach(function (item) { $('#' + control).append($('<option>', { value: item, text: item })); })
}
});
}
Did you forget to set the Forge App Keys in the Environment Variables of your project, check the page at https://learnforge.autodesk.io/#/environment/setup/netcore_da
Related
I am currently using jsTree v3.3.10 and attempting to load the structure via a Web API call.
JavaScript:
$('#ksbBrowser').jstree({
core: {
data: {
type: 'GET',
dataType: 'json',
contextType: 'application/json',
url: function (node) {
if (node.id == "#") {
return '/api/search/talent/ksbtree/root';
}
else {
return '';
}
},
data: function (node) {
return { id: node.id };
}
}
}
});
C# WebAPI EndPoint Code:
[HttpGet, Route("api/search/talent/ksbtree/{Type}")]
public String GetKSBTree(String Type)
{
List<DataModels.JSTreeNode> lNodes = new List<JSTreeNode>();
String sJSON = "";
switch (Type)
{
case "root":
var first = new[] {
new {
id = "root-id",
text = "KSBs",
state = new { opened = true },
children = true
}
};
sJSON = JSONHelper.Serialize(first);
break;
default:
break;
}
return sJSON;
}
I am getting json returned via the call and the appropriate contentType headers are there, but jsTree is not loading the tree correctly. This is the sample return of the JSON via postman:
"[{\"id\":\"root-id\",\"text\":\"KSBs\",\"state\":{\"opened\":true},\"children\":true}]"
But as you can see here, jsTree is not processing the JSON correctly.
Does anyone have any idea at all what I am doing wrong.
I figured this out. The WebAPI was returning type of string and jsTree does not do it's own parseJSON internally. To fix this I changed the return type of my end point to be an HTTPResponseMessage.
public HttpResponseMessage GetKSBTree(String Type)
Then I format the response message and return it:
HttpResponseMessage rmMessage = new HttpResponseMessage() { Content = new StringContent(sJSON) };
rmMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return rmMessage;
With the following code snipped in angular2. the url is working beginning given as aspected. If i run processTab without running it through chrome.tabs.query's asynchronous callback. it works perfectly but if i run it within the callback. the value is being passed to the processTab function but it is not working properly.
Not Working**
randomFunction() {
var self = this,
curl:string;
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
// self.updateUrl = tab.url.replace(/.*?:\/\//g, "")
curl = tabs[0].url.replace(/.*?:\/\//g, "").replace(/\/$/, "");
self.processTab(curl);
});
}
processTab(url:string) {
this.listService.getData(url)
.subscribe(
data => this.data = data,
error => this.errorMessage = <any>error);
console.log("the url: " + url);
}
Working:
randomFunction() {
this.processTab("www.whateverurl.com");
}
processTab(url:string) {
this.listService.getData(url)
.subscribe(
data => this.data = data,
error => this.errorMessage = <any>error);
console.log("the url: " + url);
}
but the value is being passed to processTab in both instances.
I assume chrome.tabs.query is not covered by zone.js. You need to make the code run explicitly inside Angulars zone for change detection detect model changes
class SomeClass {
constructor(private zone:NgZone) {}
randomFunction() {
curl:string;
chrome.tabs.query({currentWindow: true, active: true}, (tabs) => {
this.zone.run(() => {
// this.updateUrl = tab.url.replace(/.*?:\/\//g, "")
curl = tabs[0].url.replace(/.*?:\/\//g, "").replace(/\/$/, "");
this.processTab(curl);
});
});
...
}
}
also prefer arrow functions instead of self
I have a meteor app that allows users to update their skype name, phone number, email address, etc. To help maintain a consistent code base I have implemented an EJSON type UserModel in a common directory so it can run on the client and server.
EJSON.addType("UserModel", function fromJSONValue(value) {
return new UserModel(value);
});
UserModel.prototype = {
constructor: UserModel,
//
// EJSON Ovverrides.
//
valueOf: function() {
return JSON.parse(JSON.stringify(this), function(key, value) {
var dateFields = ["expiration", "createdAt"];
if(_.contains(dateFields, key) && typeof value === "string") {
return new Date(value);
} else {
return value;
}
});
},
typeName: function() {
return 'UserModel';
},
toJSONValue: function() {
return this.valueOf();
},
clone: function() {
return new UserModel(this.valueOf());
},
equals: function(other) {
if(!(other instanceof UserModel)) {
return false;
}
return this._id === other._id;
},
setPhoneNumbers: function(phoneNumber, queueUpdate) {
var modifier = {$set: {
'profile.phoneNumber': phoneNumber
}};
this.profile.phoneNumber = phoneNumber;
return this._saveOrQueueUpdate(modifier, queueUpdate);
},
_saveOrQueueUpdate: function(modifier, queueUpdate) {
if (!queueUpdate) {
return Meteor.users.update(this._id, modifier, function(err, res) {
});
} else {
this.pendingUpdates.push(modifier);
return true;
}
}
I call the setPhoneNumbers method on the settings page js file like so.
'blur #phonenumber':function(){
var user = Meteor.user();
var number = $("#phonenumber").val();
if(number.length){
user.setPhoneNumbers(number);
}
}
The problem with this is that whenever I call the setPhoneNumbers method, the page takes >500ms to update and locks the entire page. I looked at the docs and according to this segment, client code should never be blocking. The page only locks up when updates happen so I know it has something to do with the UserModel. Any insight to what could be causing this would be very helpful. The page is extremely slow and it is unacceptable for a production app.
I am using a jQuery plugin, jTable. The plugin has the following function to load the table:
$('#PersonTable').jtable('load', { CityId: 2, Name: 'Halil' });
The values in the load function is send as POST data. The plugin also sends two query string parameters (jtStartIndex, jtPageSize) through the URL for paging the table.
An example in the documentation shows a function on how to handle this in ASP.NET MVC but not in Web API Example :
[HttpPost]
public JsonResult StudentListByFiter(string name = "", int cityId = 0, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
//Get data from database
var studentCount = _repository.StudentRepository.GetStudentCountByFilter(name, cityId);
var students = _repository.StudentRepository.GetStudentsByFilter(name, cityId, jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
How my function currently looks: It works fine except that I can't manage to read the POST data (name param):
public dynamic ProductsList(string name = "", int jtStartIndex = 0, int jtPageSize = 0 )
{
try
{
int count = db.Products.Count();
var products = from a in db.Products where a.ProductName.Contains(name) select a;
List<Product> prods = products.OrderBy(x => x.ProductID).ToList();
return (new { Result = "OK", Records = prods, TotalRecordCount = count });
}
catch (Exception ex)
{
return (new { Result = "ERROR", Message = ex.Message });
}
}
My jTable load: (This get called when the user enters text in a input)
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
I would appreciate any help with how to read both the string parameters in the URL and the POST data in a Web API function.
EDIT:
I used an alternative way to send the data to the API. Instead of sending it in the load function formatted as JSON I used a function for the listAction and sent the data through the URL (See jTable API reference for details):
listAction: function (postData, jtParams) {
return $.Deferred(function ($dfd) {
$.ajax({
url: 'http://localhost:53756/api/Product/ProductsList?jtStartIndex=' + jtParams.jtStartIndex + '&jtPageSize=' + jtParams.jtPageSize + '&name=' + $('#prodFilter').val(),
type: 'POST',
dataType: 'json',
data: postData,
success: function (data) {
$dfd.resolve(data);
},
error: function () {
$dfd.reject();
}
});
});
}
To reload the table based on your filtered results:
$('#ProductTable').jtable('load');
Instead of this:
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
Try applying the [FromBody] attribute to the name parameter
public dynamic GetProductList([FromBody]string name = "", int jtStartIndex = 0, jtPageSize = 0)
{
...
}
The default binder in Web API will look in the URI for simple types like string, specifying the FromBody attribute will force it to look in the body.
Datacontext.js
var manager = new breeze.EntityManager('breeze/BreezeData');
function getMenuItems() {
var query = new breeze.EntityQuery("Products").take(5);
return manager.executeQuery(query);
}
Products.js
function loadProducts() {
return datacontext.getMenuItems().then(function (data) {
data.results.forEach(function (item) {
self.menuProducts.push(item);
});
}).fail(function (data) {
logger.logError('Failed to load Products', null, "", true);
});
}
Action Method
[HttpGet]
public IEnumerable<MenuItem> Products()
{
var venueId = GetCurrentVenue().ID;
return _contextProvider.Context.MenuItem.Where(mi => mi.Venue.ID == venueId);
}
It returns almost 45 records but i am using take(5) here and that take isn't working and returning the same result.I am a newbie so i have just started to implement it.
Thanks in advance..
Change action method to:
[HttpGet]
public IQueryable<MenuItem> Products()
{
var venueId = GetCurrentVenue().ID;
return _contextProvider.Context.MenuItem.Where(mi => mi.Venue.ID == venueId);
}
In case it still doesn't work, try adding orderBy in case server isn't sure what would actually be first 5 items.