Dynamics CRM OnPrem NavigateTo - dynamics-crm

I am using Dynamics CRM onPrem version 9.0.10,
In the unified interface I try to use navigateTo function as documented in here :
https://learn.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/xrm-navigation/navigateto
But I am getting an error in the error callback function that says that an error occured with this code -2147220715,
Here is my code :
var pageInput = {
pageType: "webresource",
webresourceName: "el_AddBenefits.html" // my html page - name taken from crm
};
var navigationOptions = {
target: 2,
width: 400,
height: 300,
position: 1
};
Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
function success(result) {
debugger;
// Handle dialog closed
},
function error(result) {
debugger;
// Handle errors - here i am getting my -2147220715 error
}
);

CRM online gets frequent updates and major upgrades twice a year. Whereas on-premise version gets almost a year delayed upgrade/updates.
So please follow the release notes for on-prem updates and keep an eye for such features, as you may know like online - you may not get a chance to try early access for such stuffs in on-prem sandbox instances.

Related

Microsoft teams bot getting members of a channel

in our use case, we have the team channel id with me. This is captured and stored into the DB in the event below
this.onTeamsChannelCreatedEvent(async (channelInfo: any, teamInfo: any, turnContext: any, next: () => Promise<void>): Promise<void> => {
}
We are running a periodic job and need to find out the members of a channel to perform some operations. So, how can i find members info from the channelid?
I have seen examples which using the context or context.activity. But in this case context wont be available. we are using nodejs v4.
My code here is
var client = new ConnectorClient(credentials, { baseUri: channel.serviceUrl });
client.fetchMembers(channel.serviceUrl, channel.channelId,
(err, result) => {
if (err) {
functions.logger.log("failed to fetch team members")
}
else {
functions.logger.log("Team members are", result)
}
}
);
This now throws error
TypeError: client.fetchMembers is not a function
i have also tried client.fetchMembers but similar error.
There are two main ways you can do this:
Using the Microsoft Graph, in particular see the List Members operation.
By having a bot registered in the channel, which it sounds like you have already. You don't need an 'activity' at all, you can do this any time by accessing the Conversations object. In fact, this code doesn't even need to run in your "bot" project at all - as long as the bot is added to the team/channel, it will work to use the bot's credentials. You can see sample code here in the Microsoft docs, and I have a sample from a recent conference session, doing this in dotnet from a console app over here.
One thing that's worth noting, the members of a channel and the members of a Team are largely the same (only excluding Private channels), so that's why some of these options refer to the Team or Group.
You'll want to use teamsInfo.getTeamMembers() or teamsInfo.getPagedMembers() (if you want a paginated list), as in this sample:
async getPagedMembers(context) {
var continuationToken;
var members = [];
do {
var pagedMembers = await TeamsInfo.getPagedMembers(context, 100, continuationToken);
continuationToken = pagedMembers.continuationToken;
members.push(...pagedMembers.members);
} while (continuationToken !== undefined);
return members;
}

Handle the cancel event on paypal client with braintree

I am trying to handle the event in which the user clicks the cancel button when he opens the PayPal client.
The integration is done with Braintree.
Here is the setup:
braintree.paypal.create({
client: clientInstance
}
},
I've seen that braintree has a handle for this event (called 'onCacncelled') but works only on v2. I have asked them what to do, but their solution does not work because uses the setup property of briantree object, which does not exist in v3. Or at least this is what js error tells me.
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
In v3 you must tokenize the PayPal instance to launch the PayPal login flow. Instead of the onCancelled callback function like in v2, in v3 it is in the error handling where you can direct tokenization errors or premature flow closures for added control.
See example and link below:
https://braintree.github.io/braintree-web/3.11.0/PayPal.html#tokenize
paypalInstance.tokenize({
flow: 'vault' // Required
// Any other tokenization options
}, function (tokenizeErr, payload) {
button.removeAttribute('disabled');
if (tokenizeErr) {
// Handle tokenization errors or premature flow closure
switch (tokenizeErr.code) {
case 'PAYPAL_POPUP_CLOSED':
console.error('Customer closed PayPal popup.');
break;
case 'PAYPAL_ACCOUNT_TOKENIZATION_FAILED':
console.error('PayPal tokenization failed. See details:', tokenizeErr.details);
break;
case 'PAYPAL_FLOW_FAILED':
console.error('Unable to initialize PayPal flow. Are your options correct?', tokenizeErr.details);
break;
default:
console.error('Error!', tokenizeErr);
}
} else {
// Submit payload.nonce to your server
}
});

Is there a way to continue test scenario execution after step failure in a previous scenario?

Whenever there is a step failure while running on a remote server, I would like to capture the failed step and then continue running the remaining scenarios. The captured step would then be included in a file for reporting purposes. Is this a possibility? All replies I've seen elsewhere just say you should fix the test before moving on. I agree, but I only want the tests to stop when running locally, not remotely.
➜ customer git:(pat104) ✗ cucumber.js -f progress (pat104⚡)
...F-----Failed scenario: View and select first contact from contact history
...F-Failed scenario: View and select a contact from multiple contacts in history
..................................................F---Failed scenario: Navigating to profile with url and enrollmentId
...................................................F-Failed scenario: Successful MDN Search with 1 result returned. Tech Selects and continues
.............FFailed scenario: Successful MDN with multiple results
Turns out, one of the step-definitions was using .waitForExist incorrectly. The test was written:
this.browser
.waitForExist('#someElement', 1000, callback)
Callback isn't a parameter for .waitForExist, rewrote to:
.waitForExist('#someElement',1000).then(function (exists) {
assert.equal(exists, true, callback);
})
This is the default behavior, isn't it? Example command
cucumber.js -f json > cucumberOutput.json
Well, that you need to manage in your test itself using callback.fail(e) like below. You can use library like grunt-cucumberjs to add these errors to nice HTML reports.
this.Then(/^the save to wallet button reflects the offer is saved$/, function (callback) {
merchantPage(this.nemo).doStuff().then(function () {
callback();
}, function (e) {
callback.fail(e); //add this to report
});
});
Or you could use Hooks and check whether a scenario is failed and report (take screenshot or add logging etc.)
this.After(function (scenario, callback) {
var driver = this.nemo.driver;
if(scenario.isFailed()){
driver.takeScreenshot().then(function (buffer) {
scenario.attach(new Buffer(buffer, 'base64').toString('binary'), 'image/png');
});
}
driver.quit().then(function () {
callback();
});
});

Meteor: Make Meteor.method return a callback

New to Meteor, and I love it so far. I use vzaar.com as video hosting platform, and they have a node.js package/API which I added to my Meteor project with meteorhacks:npm. Everything in the API works great, but when I upload a video, I need to fetch the video ID from the API when successfully uploaded.
Problem:
I need to save the video id returned from the vzaar API after uploading, but since it happens in the future, my code does not wait on the result and just gives me "undefined". Is it possible to make the Meteor.method wait for the response?
Here is my method so far:
Meteor.methods({
vzaar: function (videopath) {
api.uploadAndProcessVideo(videopath, function (statusCode, data) {
console.log("Video ID: " + data.id);
return data.id;
}, {
title: "my video",
profile: 3
});
console.log(videoid);
}
});
And this is how the Meteor.call looks like right now:
Meteor.call("vzaar", "/Uploads/" + fileInfo.name, function (err, message) {
console.log(message);
});
When I call this method, I immediately get undefined in browser console and meteor console, and after some seconds, I get the video ID in the meteor console.
Solution
I finally solved the problem, after days of trial and error. I learned about Fibers (here and here), and learned more about the core event loop of Node.js. The problem were that this call answered in the future, so my code always returned undefined because it ran before the api had answered.
I first tried the Meteor.wrapAsync, which I thought were going to work, as it is actually the Future fiber. But I ended up using the raw NPM module of Future instead. See this working code:
var Future = Npm.require('fibers/future');
Meteor.methods({
vzaar: function (videopath) {
var fut = new Future();
api.uploadAndProcessVideo(videopath, function (statusCode, data) {
// Return video id
fut.return (data.id);
}, {
// Video options
title: "hello world",
profile: 3
});
// The delayed return
return fut.wait();
}
});
Remember to install the npm module correctly with meteorhacks:npm first.
I learned about how to use the Future fiber in this case via this stackoverflow answer.
I hope this can be useful for others, as it was really easy to implement.

SignalR opens new connection for the same user

I am new to SignalR and trying to implement long running result pooling. I have added JS to my ASP.NET MVC app and created bug class.
JS
<script type="text/javascript">
var message= $.connection.messageHub;
$(function () {
message.addMessage = function (htmlstring) {
alert(htmlstring);
};
$.connection.hub.start(function () {
message.longRunningMethod('#HttpContext.Current.Session.SessionID');
});
});
</script>
c# code
[HubName("messageHub")]
public class MessagesHub : Hub
{
public void longRunningMethod(string sessionId)
{
var repeatChecking = 0;
while (repeatChecking < 3000000)
{
Caller.addMessage("Test");
repeatChecking++;
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
}
The code works fine but there is one problem. Every time the same user refresh web page new Hub class is created and new longRunningMethod method is executed. I would like to resume connection and attach to the same hub instance and resume receiving messages. Could anyone explain how to implement this?
Hubs are created and destroyed very frequently so never put any data that you expect to last on them (unless it's static).
I'm not quite sure why you're looking to have a long running method that can take in data (because SignalR is always up and available to take in/handle data) but here's how you can do it:
Checkout the SignalR stock ticker example (you can pull it in via Nuget). It creates a single instance class that fires up a timer. That timer is used to broadcast data down to the clients. https://github.com/SignalR/SignalR-StockTicker
You can also check out ShootR. It's a multiplayer game built with SignalR that does much of the same. Creates a background timer that acts as the game loop on the server and then pushes data down to clients. https://github.com/NTaylorMullen/ShootR
Ultimately your solution will involve either making a singleton or a static timer that acts as your "long" running method.
Hope this helps!

Resources