ng-admin file uploadInformation get entity id - angularjs

In ng-admin edit view I need to change file upload url with id as below , but I don't know how to fetch id of selected entity in uploadInformation base url like {{entry.values.id}} , below is my code :
files.editionView()
.title('Edit File {{ entry.values.id }}({{ entry.values.filePath}})') // title() accepts a template string, which has access to the entry
.actions(['list', 'show', 'delete']) // choose which buttons appear in the top action bar. Show is disabled by default
.fields([
nga.field('id').label('id').editable(false),
nga.field('file', 'file').uploadInformation({ 'url': baseurl +"files/upload/{{entry.values.id}}"}),// fields() without arguments returns the list of fields. That way you can reuse fields from another view to avoid repetition
])

{{ entry.values.id }} - is an Angular expression and in this form should be used in HTML not in JavaScript.
I assume that entry is your $scope variable, hence you need to write something like this: ... .uploadInformation({ 'url': baseurl+ "files/upload/"+$scope.entry.values.id})
$scope.entry should be prepopulated in your controller's code

Related

Angular. Watch for selected values inside ng-repeat list and pass them to service

I'm new to AngularJS and tried to find solution with no success.
I have dynamic form with nested ng-repeats as custom directives. Here is my structure in plunker.
In directive "rule" i have two selects, one for parameters another one for values.
<rule ng-repeat="rule in cc.route.rules track by rule.id">
<li class="second-level">
{{ $index +1 }}
<select ng-change="ic.getParamName(mc.main.routes[$parent.$index].rules[rule.id].param)"
ng-model="mc.main.routes[$parent.$index].rules[rule.id].param"
ng-options="param.name as param.name for param in ic.params"></select>
<select ng-change="" ng-model="mc.main.routes[$parent.$index].rules[rule.id].value"
ng-options="value.code as value.name for value in ic.values"></select>
<button ng-click="ic.removeRule(rule,$parent.$index)">del</button>
</li>
</rule>
When i select the parameter it fires the function with passing the parameter's name.
In the controller of current directive i catch this parameter by switch case and pass it to the certain method in service. Then i get the list of values for this parameter.
case "Countries":
vm.values = DataService.getCountries();
break;
case "Cities":
DataService.getCities().then(function(data){
vm.values = data;
});
break;
My issue is that I want to get cities only if some country is already selected in previous ng-repeats(rules) of current route (we can catch only the last selected country if there are more than one), and when i'm adding the new rule with cities, pass the code of the country selected above as argument to the certain method in service to make http request and get cities for this country. Same issue with OS and OS versions.
How i can watch for rules in current route and path the codes of countries and OS to the service with adding new rule?
UPDATE:
Let's say we add new route and want there 2 rules with country "USA" and city "Dallas". We need to add new rule to this route, choose the parameter "Countries" in the first select and the value "USA" in the second. Then we want to choose "Dallas", but my server can return american cities only if i pass the country code "US" to http request. So at the moment when we add new rule and choose the parameter "Cities" we need to get all values from all selects above, check if there was country and get it country code, then path it to the service with getCities() method.
Thanks! And please let me know if it is not well understood.
Re-factor the User Interface
Currently as designed the UI has an Add new Rule button that allows the user to add illegal rules. As shown in the screenshot, the user has erroneously added two countries. And as stated by the OP, users can add a Cities rule before a country is selected.
The advice is to change the Add new Rule button to a drop-down menu that has illegal options disabled. When rules are added or removed, the controller should enable or disable appropriate legal items.
The ng-options directive allows a controller to enable and disable options using the disable when clause. For more information, visit AngularJS ng-options API Reference.
The UI should not allow the user to add illegal rules. Also the Submit button should be disabled until the form is complete. Users should be given advice on how to complete the form. "Add Route", "Select Rule", "Select Country", etc.
XHR Request Issues
In the PLNKR the DataService.getCities function has several problems.
//WRONG
function DataService() {
return {
getCities: function (code) {
$http.get('/get_cities?country_code=' + code)
.success(function (response) {
return(response.data);
});
The return statement doesn't return a value to the getCities function. It returns values to the anonymous function inside the .success method and the .success method ignores return values.
//BETTER
function DataService($http, $q) {
return {
getCities: function (code) {
if (isBad(code)) {
return $q.reject("BAD Country Code");
};
//Otherwise send request
var getCitiesPromise = (
$http.get('/get_cities?country_code=' + code)
.then(function onFulfilled (response) {
return(response.data);
});
);
return getCitiesPromise;
}
}
};
In this example, the getCities function checks the country code and returns a rejected promise if the code is bad. If the country code is OK, an XHR request is sent and a promise is return fulfilled with the data or rejected with the $http service error.

Angular change the value of a variable in URL

I am currently having a problem where I can not change the value of the parameters in the URL. This is my URL : http://localhost/details
I would like to add or swap an "inverse" parameter in the URL when I filter my table, like the following : http://localhost/details?inverse=false or http://localhost/details?inverse=true every time i submit the form with inverse checkbox selected or not.
Here is how to get the params from the URL:
var paramsURL = $location.search();
// If params in URL
if( Object.keys(paramsURL).length > 0) {
if ( paramsURL.hasOwnProperty('reverse')){
$scope.reverse = paramsURL.reverse;
}
}
If the URl has an inverse param to true of false, then I store it and apply it in the request. This works perfectly so far.
The problem is to change dynamically the URL when the user submits the form .
I tried the following things but no one them work:
$location.search('reverse', $scope.reverse).replace();
or
$location.search({reverse:$scope.reverse});
$scope.reverse exists because it has a default value but i can not change the URL to match its value.
Does anyone already got this problem before ? Thank you for your help.
If got your requirement correctly, you need to set new value in query params dynamically. You can try following
$location.path('/currentPath').search({key: value});
key: will be reverse
value: will be set to true or false dynamically
above setter method allows chaining for multiple values

Pass parameter to tab

I am building my first Angular app with a list of product specifications such as "Brand name" etc. The finished app will be connected to an MSSQL db.
I have a list with the saved Specifications and when I click one of them I want the following to happen:
Show Edit Specification Tab
Pass the parameter SpecificationId
Perform an http GET with current Specification Id
I set up a plunker with the app in its basic state:
http://embed.plnkr.co/4F8LMwMorZEF0a42SzTJ/
As you are already sending your id you just need to get it within your method:
Update your controller like this:
app.controller('TabController', function ($scope) { // use $scope here
and set the id in the $scope.spec object like below:
this.setTab = function (selectedTab, specId) { // get the id in the args here
this.tab = selectedTab;
$scope.spec = {id : specId}; // set the id in here
console.log($scope.spec.id);
};
and then you can bind the id value in the markup as this:
The current Specification ID is: <strong>{{spec.id}}</strong>
Updated plunkr demo.

ng $resource Fails to Dynamically Generate URI

The Problem:
I have code to set up a $resource that seems to compile without error:
var ReportsRest = $resource('/reports/:reportId', {reportId: '#id'});
ReportsRest.get({id: 123});
but when that code actually executes the request url that is generated looks like this:
GET http://localhost:5523/reports?id=123 404 (Not Found)
The id is not being parsed and dynamically loaded into the URI. Is there something that I am missing?
Plunkr
http://plnkr.co/edit/3ikqMsnDI9r9LThaQLf3?p=preview
Try this:
var ReportsRest = $resource('/reports/:reportId', {reportId: '#id'});
ReportsRest.get({reportId: 123});
Under $resource Usage, there is this block of text.
paramDefaults
Default values for url parameters. These can be overridden in actions methods. If any of the parameter value is a function, it will be executed every time when a param value needs to be obtained for a request (unless the param was overridden).
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
Given a template /path/:verb and parameter {verb:'greet', salutation:'Hello'} results in URL /path/greet?salutation=Hello.
If the parameter value is prefixed with # then the value for that parameter will be extracted from the corresponding property on the data object (provided when calling an action method). For example, if the defaultParam object is {someParam: '#someProp'} then the value of someParam will be data.someProp.
To summarize, the object you pass in needs to use the key of your paramDefaults object to get the value. That value replaces the same :key text in your URL pattern. Any value in the paramDefaults object that is prefixed with an # will be set on the returned model data as a property named whatever follows the #.
var ReportsRest = $resource('/reports/:reportId', {reportId: '#id'});
ReportsRest.get({
reportId: 123,
other: 123
}, function(data) { /* ... */ });
This makes a request to /reports/123?other=123. data, in the callback, looks like { id: 123 }.

Backbone - fetched model, set an attribute(modify), then save model, it should update but sending POST request

I created my web site having 2 types of users: admin and user. So, I created 3 pages mainpag.html, admin.html, user.html. and separate models, views, collections, routers.js files for each of them. After logging in, as I am sending users to separate HTML pages with different models, I can't automatically get user model. so I did like this:
First, I made AJAX call to server, asking for the _id (username in session, so I can get id)
from the id, I fetched the model, by model.fetch(), then I got my usermodel with all attributes.
then in the success callback of fetch, I did model.save({weight: "somevalue"}). According to me, it should update right, as the model is already available, that attribute weight also available with some old value, but it is sending POST request, also when I tried model.isNew(), it returned true. Where am I wrong? how can I update my model? I will post more details if required.
More details:
If I remove that save method, then I am getting correct attributes in the model.
If I don't remove that save method, that success and error callbacks are also appearing as attributes in the model.
Code:
addWeight : (e)->
arr=new Array()
arr['_id']=app._id
console.log "asdasd"
console.log arr
console.log arr['_id']
#user_model =new UserModel(arr)
#user_model.fetch({
success : (model,res,options) =>
console.log model
console.log res
arr=new Array()
arr['_id']=e.target.id
#arr['action']='weight' #means , update weight
##user_model.setArr(arr)
##user_model.set({weight : arr['_id']})
console.log "new : "+#user_model.isNew()
#user_model.save({weight : e.target.id})
##user_model.save({
# success : (model,res,options) =>
# console.log "model updated: "+JSON.stringify(model)
# console.log "Res : "+JSON.stringify(res)
# error : (model,res,options) =>
# console.log "Error : "+JSON.stringify(res)
#})
error : (model,res,options) =>
console.log "Error "
})
the above code is written in coffeescript, so even if you don't know coffeescript, don't worry, you can understand easily, and those # mean, it is a comment. here we follow indentation instead of braces.
one more doubt, a model's URL must be changed dynamically according to the requirement, right? what is the best way to achieve that? I am doing like this:
I am populating "array" containing the required fields that should be present in the URL. In model, s init func, I am using #arr=arr, then in URLs function, I check like this.
url : ->
if #arr['id']
"/user/#{#id}"
Is my approach right, or any better approach is there for dynamically setting URLs. Or can I directly set the URLs like this:
#user_model.setUrl "/someurl/someid" //this setUrl method is available in model's definition
#user_model.fetch() or save() or watever that needs url
Just a hunch, but you mentioned that you call model.fetch() to retrieve the _id field. Be sure to either return an id field instead _id (notice the underscore).
The call to model.isNew() returning true is an indicator that the id property was never set from the model.fetch() call.
I look forward to a possible further explanation with your code...
Looking at your code:
/* The model needs an 'id' attribute in order to marked as not new */
#user_model = new UserModel(id: arr['_id'])
Actually if you call
model.set({weight: "somevalue"});
It will update the value in the model, but it won't send a POST request
model.save(attribute);
Actually calls Backbone.sync as you probably know.
EDIT :
You might want ot set
m = Backbone.Model.extend({
idAttribute: '_id'
});
to every model, because the isNew method actually checks if the model has id attribute
Regarding to this you could see here that .set doesn't call backbone.sync here : http://jsfiddle.net/5M9HH/1/

Resources