what is a Backbone model.save( ) call expecting on a POST operation? - backbone.js

I'm calling save() on a backbone model to do a POST operation on the back-end. The operation completes successfully server-side (I can see the record added and the response status comes back as 200). Currently the RESTful api call is returning the ID of the inserted record in the response body. I have success and error callbacks defined that I pass to the save call, but success is never called. Instead, the Backbone code is choking on that ID that gets returned from the REST call. Is there a better way for me to handle this from the client end or should the REST api implementation be returning something else?

By default I believe it expects the changed properties of the object as JSON. See: http://documentcloud.github.com/backbone/#Sync

Related

obtain the result or HTTP response of an add operation of ngrx/data

As described in the entity dataservice documentation , the add operation expects an entity to be saved on the backend. What it doesn't say is that it expects the created entity to be returned from the backend (with an ID etc). My backend does that and it works as expected, however
when I tap into the add operation, which returns an Observable, at least my IDE gives me Observable methods to continue... it's best demonstrated with a piece of code
this.myEntityService.add(myNewEntity).pipe(
tap(data => console.log('data:', data))
)
Nothing is logged to the console at all.
My question is, how do I get what's returned from the HTTP service? e.g. the entity, persisted to the backend database?
The problem was, I didn't subscribe to the Observable that add returns.
I assumed the data is being emitted regardless of a subscription.
So the correct way to receive the result is
this.myEntityService.add(myNewEntity).subscribe(data => {
console.log('data:', data);
});
subscribing to it.

Ensuring $httpBackend flush for series of requests

I have a need to test an in-house angular service implemented under Angular 1.5.9 with jasmine/karma.
I need to write a test which checks that the response of a particular service function is as expected. To do this I am constructing a mock object, instantiating the service, calling the function to be tested and using expect().toBe() to check the returned value.
Unfortunately, the service makes numerous calls to it's own functions, many of which make further calls using the $http angular service. It does this in order to populate objects such as user data, locale and other bespoke product information. Suffice to say that I am not in a position to refactor the service into a better architecture; I must simply construct this test.
As there are so many calls to $http I intend to mock all the data it would request using a series of lines such as this:
var mockGetCartData = { "d": null, "message": null }; // at the top of the describe
$httpBackend.when('GET', /(.*)\/order\/api\/v1\/GetCart/).respond(200, mockGetCartData); // in the beforeEach
When I call the function to be tested I am immediately calling $httpBackend.flush() but, as the test is failing, I am concerned that what I need to do is cause each (faked) $http call to be flushed before the next is made.
Do I need to do this or is setting up all of the $httpBackend.when().respond() entries, acting on the test function and then calling a single flush() enough? If this is not enough, what should I do?
You do not need to call flush() for each request that is made as it flushes all pending requests.
See the Documentation: https://docs.angularjs.org/api/ngMock/service/$httpBackend
or source: https://github.com/angular/angular.js/blob/master/src/ngMock/angular-mocks.js#L1830
However, if the $http requests in the method under test are chained together (so subsequent requests are only made after the previous request is resolved) then you will need to flush() for every request in the chain. Without seeing the code under test that's all the help I am able to give.
You have to mock the only required http call in It block and flush it after the function call. Otherwise it will try to flush unexpected http calls which will result in error.

How to Make a Synchronous Call an Asynchronous Call in Angular?

I have an app that shows statuses for internal processes. It also has a separate view that allows you to set up new records. To set up a new record, you fill out a form, and upon submit a call is made to my nodejs server that:
inserts the record into a table
kicks off a stored procedure
routes you back to the status page
The issue here, is that the page hangs while this happens, as sometimes the stored procedure takes a minute or two to run. So you wait for a couple minutes, and then are routed back to the status page.
Now, I don't actually care to see any exit code for this stored proc on the front end, as you will see the status of it on the status page. I'm wondering if there's a way for me to kick this process off, but not have the front end care about the return.
I've tried adding in the $location.path() before the $http call to the server, but then the $http call never happens.
Any ideas?
Thanks!
You can wrap the stored procedure call in a promise. The browser will make the call and continue on without waiting for it to complete and you can react appropriately in the resolve or reject functions. You can use angular's $q service:
insertRecord();
$q(function() {
storedProcCall();
});
redirect();

What is the difference between .all() and .one() in Restangular?

What is the difference between these two? Both seems to make a GET to /users and retrieve them.
Restangular.one('users').getList().then(function(users) {
// do something with users
});
Restangular.all('users').getList().then(function(users) {
// do something with users
});
I understand that you can do one('users', 123) and it will retrieve /users/123 but without the second argument it seems to be the same thing. Why not just have one method in that case?
The one() function has a second argument that accepts an id e.g. .one('users', 1).
one('users', 1).get() translates to /users/1
all('users').getList() translates to /users
Unlike all(), one() is not generally used with .getList() without argument. However, if you were to call .one('users', 1).getList('emails') or .one('users', 1).all('emails').getList(), then you would make a GET request to /users/1/emails.
My guess is that they are there for expressing an intention of what you are going to do. I would understand those as a way to build the url, expressing if you are accessing to the whole resource or to a specific one.
In the end, they are gonna build and do a GET request but because you do a GET and retrieve some data it does not mean that it should be used in that way.
Example extracted from https://github.com/mgonto/restangular/issues/450
getList can be called both ways. If it's called in an element one,
then it needs a subelement to get to a Collection. Otherwise, it
fetches the collection. So the following is the same:
Restangular.one('places', 123).getList('venues') // GET /places/123/venues
Restangular.one('places', 123).all('venues').getList() // GET /places/123/venues
As you can see, it is more expressive to call one('places', 123).all('venues') to understand that you just want the venues located in the area/place 123.
Maybe the following url will help you:
https://github.com/mgonto/restangular/issues/450
I've recently discovered a difference between these methods. Yes, both of them make the same get requests, but the results you get might surprise you (as they surprised me).
Let's assume we have an API method /users which returns not strictly an array, but something like this:
{
"result": [{...}]
}
So an array is returned as a value of some prop of the response object. In this case get() and getList() work differently. This code works well:
Restangular.get('users').then(function (response) {...});
Your response handler gets invoked after response has been received. But this code doesn't seem to work:
Restangular.all('users').getList().then(function (response) {...});
Response handler is not invoked, despite that request completed with status code 200 and non-empty response. Browser console doesn't show any errors and network monitor shows successful request.
I've tested this with Restangular 1.5.2 so probably this is already fixed in newer versions.

How do I cancel an asynchronous operation in Silverlight/WCF?

I am calling an asynchronous service from my Silverlight app and I want to be able to cancel that call after it is made. There is an option for e.Cancelled once the service has finished (i.e. If e.Cancelled Then), but how to you set that cancelled to true after you have called it? How do you cancel that asynchronous call?
Let me clarify a bit... what I am trying to do is call the SAME method twice, one right after the other, and get the results of the last call into my collection. If I call an asynchronous method twice there is no guarantee that the second call will return first, so I may end up with the results of the first call coming in last and having the wrong results in my collection. So what I would like to do is cancel the first call when I make the second so I don't get results back from the first call. Seeing as how there is a Cancelled flag in the completed event args I figure you should be able to do this. But how?
It's async... the transfer is passed off to a remote server and it does not return until the server is done with it.
Basically the server will keep going, but you don't have to wait for the response. Disconnect your service completed event handler and pretend it was never called. That will give the effect of cancelling the operation.
If you really need to cancel something in progress on the server you would need to make another call to the server to cancel the first call. Assuming the first call is a very slow one, this might be possible.
Update (as question changed)
In the case you specify, it will be up to the server to cancel a operation in progress if a second one comes through, not up to the client. e.Cancelled is set server-side.
However... :)
You have exposed a client usability issue. Shouldn't you also delay sending any service request until an idle delay has passed. That way rapid selections will not result in multiple service calls.
Also... :>
You may also want to send a sequence number to your service calls and return that as part of the result. Then you will know if it is the latest request or not.
It sounds like what you really want to do is ignore the responses of all but the most recent call.
Set a unique ID (could be request #, a Guid, timestamp, or whatever) with the request, and make sure the service sends that same value back. Keep around the ID of the most recent request and ignore response that don't match that ID.
This will be safer than cancelling the first request, since if the service has already started sending the response before the cancel request happens, you still get your error condition.

Resources