Event Handler later than OnPublished - csom

Are there any Project Server event handler events later than the "OnPublished"-event when creating a new project?
The time when the on published event occurs seems to be to early. Loading the project FieldValues does not work. They are always null.
PublishedProject project = projCollection.First().IncludeCustomFields;
projectContext.Load(project);
projectContext.Load(project.IncludeCustomFields);
CustomFieldCollection fields = project.CustomFields;
projectContext.Load(fields);
projectContext.ExecuteQuery();
Dictionary<string, object> fieldValues = project.FieldValues;
When executing the same code for an existing project everything works fine.
Instead I could do a timeout for x seconds but I would prefer a later server event where all values have already been set.
Edit:
Seems there was something wrong with my other code before executing this. Custom Fields and FieldValues are loading correctly now.
But loading the projectSiteUrl afterwards is still to early at this point. The ProjectSiteUrl stays null.
projectContext.Load(project, p => p.ProjectSiteUrl);
projectContext.ExecuteQuery();

Once a project is completely published, OnProjectChangedRemote event of ReportingEventReceiver Class gets fired.
When a new project is created and the creation process completes, OnProjectCreatedRemote event of ReportingEventReceiver Class gets fired.

I used PSI not CSOM and "ProjectSiteUrl" is null after first publish(OnPublished event).
For first publish I used OnWssWorkspaceCreated event which is in WssInteropEventReceiver class or interface.

Related

ng-block-ui not working with Angular 7 concatmap

I'm using NgBlockUI and BlockUIHttpModule with blockAllRequestsInProgress set to true in an app I'm working on. In general it's working fine, but on one page I'm using a concat map to perform some action and then update the data. The first request, the update, triggers BlockUI fine, but the second one doesn't. Otherwise, it executes properly. It's just a little jarring for the user since the results seem to update without warning. Here's the code for the function:
onUpdate(event: items[]) {
this.updateService.update(event).concatMap(
_ => this.seachService.search(this.cachedSearch)
).subscribe(
resp => this.handleResponse(resp),
err => this.handleError(err)
);
}
I tried calling BlockUI directly, but still no luck. As a last resort, I'm going to make the whole thing one request, but I'd like to at least understand why this isn't working.
This happened to me as well. This issue occurs for sequential HTTP calls (usually with await) wherein the second request is not blocked by ng-block-ui.
As fix what I did was set blockAllRequestsInProgress to false. The behavior is just the same but setting it to false yields more predictable results:
BlockUIHttpModule.forRoot({
blockAllRequestsInProgress: false,
requestFilters: [urlFilter]
}),
I've also updated to ng-block-ui to latest version as of this writing:
"ng-block-ui": "^2.1.8",

getFullYear() is not a function

I am developing web app by using Angular. When I upgrade my app to Angular7, Date function is not working. It gave me error such as
DateTime.getFullYear is not a function
It was ok before I upgraded to Angular7. In package.json:
"typescript": "^3.1.1", "#angular/cli": "~7.0.2",
"#angular/complier-cli": "~7.0.0".
What is going on?
Remember next time you post a question to paste the code relating to your error so that someone can have a look at it, since the same error can result from different code.
After upgrading my ng6 app to ng7 my DateTime.getFullYear worked fine, until I changed something about it, and it suddenly gave the same error. Everything seemed fine.
Checking my date object like below returned an object just the way it should
dateFunction(longdate) {
console.log(typeof(longDate)) // This returned 'object' which is correct
longDate.getFullYear() // Would get the same error here
}
So I tried passing in a fresh date object into the function, and not one being send via parameter like this:
dateFunction() {
longDate = new Date();
console.log(typeof(longDate)); // This returned 'object' which is correct
longDate.getFullYear(); // This worked fine now
}
And this would work fine, so I realized it is not my getFullYear() function that is wrong, but my parameter that is corrupt.
But here is the strange part, so I went to the parent component and did the same thing there - I deleted the old code and made a fresh longDate = new Date() and send it through to my function, and suddenly it was working. The exact same code, but I just re-wrote it.
Try creating a fresh date just before your function, pass it in and see if it works. If it works then it is not your function but the old date variable that is corrupt.
PS: I just feel that I have to say that you must use the new keyword (see examples above) when creating your initial date variable, or it will also throw the error...

Multiple instances of the same Active Form

I have an Active Form, I made some years ago, compiled as an ocx. It is installed on the tool palette.
I've only used one instance of it on each main application, and it has worked fine.
Now I need to use many instances of this active form from the same main application. So I drop a couple of them from the tool palette to my main application. But no matter which of the active forms I use (it has an built in form I open) from the application, the same instance of it shows up. And this is not what I want.
I can't figure out if the active form should been created in a different way, or if I should use it different from the main application.
The active form is built with c++builder XE, and the main application is built with XE6.
This is the way I create the instances:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ActXList = new TList;
TMyActX *TempActX;
for(int i=0; i<10; i++)
{
TempActX = new TMyActX(Owner);
TempActX->Parent = this; //Tried also with NULL and a new TForm(this), same result
ActXList->Add(TempActX);
TempActX->Init(i); //This adds i to a string in the created instance
}
MyActX1->Init(20); //Adds 20 to a string in the design time created instance
MyActX2->Init(21); //Adds 21 to a string in the instance
}
And here I open the different instances:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TMyActX *TempActX;
//A Combobox chooses the instance to show
if(ComboBox1->ItemIndex < 10)
{
TempActX = (TMyActX *)ActXList->Items[ComboBox1->ItemIndex];
TempActX->ShowForm();
}
else if(ComboBoxTerminaler->ItemIndex == 10)
MyActX1->ShowForm();
else if(ComboBoxTerminaler->ItemIndex == 11)
MyActX2->ShowForm();
//No matter which instance is chosen to be shown,
//the label with the init-string shows "0 1 2 3...9 20 21" for all of them
}
For testing, the integer i is added to an Label in ->Init(). TMyActX has an internal form where the Label is shown. If I open this from (with any of the created instances), the Label shows "0 1 2 3 4...". Therefore I make the conclusion that ->Init() calls the same instance, and the same form is opened no matter which created instance I use to open it.
The same thing happens if I drop two instances to my main form at design time. The same Label is shown if I open the ocx-form.
The reason I use an ocx, is that the ocx is a part of a payment solution, that is certified by a external organization. So I don't want to not mess around with it, if possible. But I have access of the code for it, and for testing I can change it.
if you got access to the TForm class of your form then just create new instances on runtime like:
TForm *win[10];
for (int i=0;i<10;i++) win[i]=new TForm(this);
where this is pointer to parent VCL form created by IDE. This works for me but I do not use ocx instead I include the 3 files per window (*.h,*.cpp,*.dfm) however I am bound to BDS2006 so on newer versions of builder things may be a bit different ...
Do not forget that to make this work you can not have global variables in your form, and have proper close/destroy method of the win[] on apps close.
You can access your windows by their pointer (to show or hide them or whatever) also you should handle the manual close of window (so you do not access dead pointer latter on)

Box::info showing "refreshEx"

I have a method that displays a validation result using the syntax
Box::info(message,title);
However, the first time I run the code it displays the correct title, but the message refreshEx.
Debugging the code the message that is being used is correct, Valid Account Number, but what displays is refreshEx. If I rerun the process the correct message is displayed, this only happens the first time.
Just in case it matters the flow is
Form - DoValidation method creates Class to call...
Class - public AccountValidation method that calls...
- private displayValidation method that contains this code
Thanks...
I have seen this error (unfortunately), in an AX 2009 installation, launched from code behind a button in a form:
if(HIEItemOrderSetup.RMAvailable < HIEItemOrderSetup.RMQuantity)
{
ok = DialogButton::Ok == box::okCancel("#HIE848",DialogButton::Ok,"#HIE849");
}
As far as I can tell it only occurs when you have a breakpoint on your form, when you are updating it. Removing the breakpoint will show the original message or at least this is what I have found.
If the message contains some fields from the database, try to execute a reread() or refresh() or refreshEx() method (depending on the context) to the datasource before showing the value through the info box.
May be the cached data is not refreshed after an update or insert.
EDIT:
If you are specting a return parameter from an Event, don't forget that this is an async process. An example on MSDN:
http://msdn.microsoft.com/en-us/library/gg843664.aspx

New Object not triggering createRecord in DataSource

In my responder I have:
Spanish.ADDWORD = SC.Responder.create({
didBecomeFirstResponder: function(responder) {
var store = this._store = Spanish.store.chain(); //buffer changes
var word = store.createRecord(Spanish.Word, {word: "", english: ""});
Spanish.addWordController.set("content",word);
//show the dialog
var pane = Spanish.getPath('addWordPage.mainPane');
pane.append();
pane.makeFirstResponder();
},
submit: function(){
this._store.commitChanges().destroy();
Spanish.makeFirstResponder(Spanish.READY);
}
}
Before I had the DataSource hooked-up, and I was using local, everything worked. When I click submit now no new object is created and createRecord is not being called.
A possible problem is that you are calling .destroy() immediately. This shouldn't be an issue, but as you said it was working while using fixtures (which are synchronous). Now that you are using a dataSource (which is usually asynchronous), it may be getting interrupted. Try removing the .destory(), and see if that resolves your issue.
Another option to try, is that there may be a bug in the nested store, in that if you create a new record (rather than edit an existing one), the 'did it change' test may fail (as there is nothing to compair it too), so calling commitChanges(YES) will force a commit, without the check.

Resources