Unable to POST data using collection's fetch method - backbone.js

From what I understand, I'm able to use my collection to fetch, POST data, to an api. In this case, I'm using the Bing translate api.
My fetch looks like this:
app.searches.fetch({
contentType: "application/x-www-form-urlencoded",
type: 'POST',
data: { client_id: 'test',client_secret:'test', scope:'http://api.microsofttranslator.com', grant_type: 'client_credentials'},
dataType: 'jsonp',
success: function () {
}
});
Everytime this fetch fires, it performs a GET, not a POST. Right now, my project is barren so I don't think anything is interfering. Have I written this fetch incorrectly?
EDIT:
here's the collection:
var app = app || {};
(function(){
'use strict';
// Searches Collection
//---------------------
var Searches = Backbone.Collection.extend({
//referebce to this collection's model
model: app.Search,
url: 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13'
});
app.searches = new Searches();
})();

Related

How to post data on button click using AngularJS

I have an application made with .NET core framework and pure html in the front end. I was using AJAX to post and get data.
I am new to Angular and decided to convert the front end of the application to Angular for learning purposes.
For Example, I have a button that will change the state of employees from 'Billed' to 'Available' state. The ID for available state is defined in the back end and it is '1'.
//MOVE TO BENCH BUTTON CLICK
$(document).ready(function()
{
var allVals = [];
$("#MoveToBench").click(function()
{
$('input:checkbox:checked').each(function () {
allVals.push($(this).val());
});
for (i = 0;i<allVals.length;i++){
PostBenchList(allVals[i])
}
function PostBenchList(entityId) {
var data = 'entityID='.concat(entityId).concat('&nextStateId=1');
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://localhost:1783/api/Workflow?"+data,
data: data,
dataType: "text",
success: function (data) {
location.reload();
alert("Successfully added the selected Employees to TalentPool");
},
fail: function (error) {
Console.Log(error);
}
})
}
});
});
The above code is taking an array of entityID's as input. For the Angular application, the array is not required as only one entity ID will be passed.
The API controller in the backend is :
// POST api/values
[HttpPost]
public void Post(int entityId, int nextStateId)
{
JObject jsonObject = JObject.Parse(System.IO.File.ReadAllText("Config.Json"));
string jsonFile = jsonObject.GetValue("WorkfowJsonFileLocation").ToString();
var nextState = _stateServices.Get(nextStateId);
var handler = new WorkflowHandler(nextState, jsonFile, _entityServices, 1, _stateServices, _subStateServices, _appServices);
handler.PerformAction(entityId);
}
The above code worked for me and it would change the state ID of the employee(EntityID)to 1(nextStateId)
Now I have a button in AngularJS and I want it to do the same action. How would I achieve this? As I am still in the procedure of learning, I don't have a clue how to do this. Can anyone help me to achieve this? This would help me to learn and do all similar buttons.
Thank You.
You can use ng-click and call a function to post the data,
HTML:
<button ng-click="PostData()">
Click to POST
</button>
Controller:
app.controller('PostController',['$scope',function($scope)
{
$scope.sendPost = function() {
var data = $.param({
json: JSON.stringify({
name: $scope.newName
})
});
$http.post("/echo/json/", data).success(function(data, status) {
$scope.hello = data;
})
}
}]);
DEMO APP

AngularJS Response does not match configured parameter

I've got a problem with service configuration. I want to display one user by this function:
$scope.findOne = function() {
$scope.user = Users.get({
userId: $stateParams.userId
});
};
But I am in trouble with User service :( I don't know, how should I change my the code to avoid angular error:
Error in resource configuration for action object. Expected response
to contain an array but got an {2}
Here is a code of my actual working service (without function findOne working of course:))
'use strict';
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
},
remove: {
method: 'DELETE',
url: 'users/:id',
params: {id: '#_id'}
}
});
}
]);
At a guess, I'd say your users API endpoint is expecting /users/:userId for GET requests. Your code at the moment will request /users?userId=nnn. You need to add an action for get with the ID in the URL, eg
return $resource('users', {id: '#userId'}, {
get: {
method: 'GET',
url: 'users/:id',
isArray: false
},
// etc
You can also make users/:id the default URL as long as it doesn't interfere with your other action configurations.

angular js getting data from laravel and print it

Hi I'am trying a simple example of using a controller and a factory to get some data back to the view but for some reason I can't print it.
I managed to get the ajax call to work.
If I type the
$scope.sampleStyles = [{ sample: 'text here', text : 'dasdas'}
and don't use the ajax call it works
UPDATE: if I add an alert before assigning to my scope it works (ajax has time to do his thing)
anyone know how to overcome that?
CODE:
var packageApp = angular.module("packageApp", []);
packageApp.controller("MyController", function($scope, myFactory){
$scope.sampleStyles = [];
function init(){
$scope.sampleStyles = myFactory.getSampleStyles();
}
init();
});
packageApp.factory('myFactory', function($http, $log){
var factory = {};
var sampleStyles = [];
var tempData = {};
factory.update = function(){
$.ajax({
type: 'POST',
url: '/account/fetch-sample-styles',
data: {
source: 'ajax'
},
success: function(data, textStatus, XMLHttpRequest){
tempData = data;
}
});
alert(tempData);
sampleStyles = tempData;
}
factory.getSampleStyles = function(){
factory.update();
return sampleStyles;
};
return factory;
});
Are you using the AngularJs $http service? If so it will return a promise which you then operate on. Here is more on promises from the AngularJs docs.
My guess is, you are using an ajax.get(...) with a success callback defined inside. The problem is probably due to the success callback not belonging to the "AngularJs world."
To fix this, you need to tell AngularJs that its scope has changed. Use the $[Root]scope.$apply() function, and have the scope injected into your service as a dependency.
Something like this inside the factory:
$.ajax({
url: "/api/some/end/:point",
...
success: function(data) {
$scope.$apply(function() {
$scope.sampleStyles = data; // etc
});
}
});
I strongly recommend that you look into the $http service, it makes the above code much nicer, and is designed to play nice with the $scope.
$http.get("/api/end/point").then(function(response) {
// response.data points at the page data sent back, assuming that your
// api endpoint sends back JSON of the likes of
// { status: "SUCCESS", styles: [...] }
$scope.sampleStyles = response.data.styles;
});
EDIT:
Now that you posted some code, it seems like the root of your issue is based on the fact that the ajax get is an async call. Why are you even messing with using a temporary variable? Why not the following?
factory.update = function(){
$.ajax({
type: 'POST',
url: '/account/fetch-sample-styles',
data: {
source: 'ajax'
},
success: function(data, textStatus, XMLHttpRequest){
sampleStyles = data;
}
});
}
If you really wanted to make the $.ajax call blocking, you can set async: false in the $.ajax properties.
EDIT 2:
Fixed some broken links, sorry I am a SO newb :(

Wrapping my head around a unique backbone.js collection

I'm working out my first backbone.js app and have run into a bit of a wall. Perhaps someone can help me past this hurdle (gap in my understanding). What I want/need to do is to return the collection data to my router, so I can bind it to a Kendo UI Grid, but I'm not seeing any of the search results in my collection... I figure I must be missing something fundamental, but I'm not sure what it is.
Here is what I have so far:
ES.Router = Backbone.Router.extend({routes: {
'': 'search',
'search': 'search',
'results': 'results'
},
results: function() {
var resultsData = new ES.Results();
var boo = resultsData.fetch({
data: JSON.stringify({"query":"myquery"}),
type: 'POST',
contentType: 'application/json'
});
console.log(boo);
}});
ES.Result = Backbone.Model.extend();
ES.Results = Backbone.Collection.extend({
model: ES.Result,
url: '/search/query'
});
There are a few issues here:
A fetch should be a GET, not a POST, because a fetch should not save or modify anything
Maybe just a personal preference, but I'd url as a function, so as to avoid trying to modify the AJAX request options manually.
The fetch call will always be asynchronous, so you need to either add a success callback in the options hash, or add a listener to the collection's reset event
I'd write the collection like this:
ES.Results = Backbone.Collection.extend({
initialize: function() {
this.query = "test";
},
model: ES.Result,
url: function() {
return '/search/query?query=' + this.query;
}
});
Then set the search when you create the collection:
var resultsData = new ES.Results();
resultsData.query = "soccer";
And use success and/or the on("reset") event to handle the result:
resultsData.on("reset", function(collection) {
console.log(collection);
});
console.log("Fetching....");
resultsData.fetch({
success: function(collection, response) {
console.log("Got data!" + collection.length);
},
error: function(collection, response) {
console.log("Error: " + response.responseText);
}
});
​

How to specify url and header in backbone to use crud method on my model?

i need to make request on server that needs of particulary api key and i need to use the crud method tu update my model and as soon as...
For example i have this code in ajax to get element from server:
function getapi() {
$.ajax({
url: 'https://api.parse.com/1/classes/autolavaggi/QSfl*****',
type: 'GET',
dataType: 'json',
success: function(obj) {
alert("nome autolavaggio "+obj.nome);
},
error: function() {
alert('Errore');
},
beforeSend: setHeader
});
}
//GET GET GET GET GET GET GET GET Header Header Header Header
function setHeader(xhr) {
xhr.setRequestHeader('X-Parse-Application-Id', 'aqLJlmE2rRXBOy***************');
xhr.setRequestHeader('X-Parse-REST-API-Key', 'gvT2Isd5vAvjgq*****************');
}
How can i do to assign this particular ajax call to crud method save,fetch or another??
Each of the crud methods accept an options hash that will get forwarded to the ajax call. In the case of a collection fetch:
var Model = Backbone.Model.extend({});
var Collection = Backbone.Collection.extend({
model: Model,
url: 'https://api.parse.com/1/classes/autolavaggi/QSfl*****'
});
var setHeader = function (xhr) {
xhr.setRequestHeader('X-Parse-Application-Id', 'aqLJlmE2rRXBOy***************');
xhr.setRequestHeader('X-Parse-REST-API-Key', 'gvT2Isd5vAvjgq*****************');
}
var collection = new Collection();
collection.fetch({ beforeSend: setHeader });
Alternatively, override sync:
var sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('X-Parse-Application-Id', 'aqLJlmE2rRXBOy***************');
xhr.setRequestHeader('X-Parse-REST-API-Key', 'gvT2Isd5vAvjgq*****************');
};
// Update other options here.
sync(method, model, options);
};

Resources