Can i pass DateTime parameters in ui-router? - angular-ui-router

$stateProvider
.state('messagelogs', {
controller: 'Messages',
url:'/messageLogs/{pageIndex:int}/{itemsPerPage:int}/{text:string}/{fromDate:date}
})
Will ui-router recognize :date?

You can create your own type. So, when you say $stateParams.someDate property you will always get instance of Date.
Here is some example, you can improve it
(function (angular, Date) {
angular.module('some-module')
.config(addCustomUrlParamType);
addCustomUrlParamType.$inject = ['$urlMatcherFactoryProvider'];
function addCustomUrlParamType($urlMatcherFactoryProvider) {
$urlMatcherFactoryProvider.type('myDate', {
name: 'myDate',
decode: function (myDateValue) {
var timestamp;
if(angular.isDate(myDateValue)) {
return myDateValue;
}
timestamp = Date.parse(myDateValue);
if(!isNan(timestamp)) {
return new Date(timestamp);
}
},
/**
* #description
* Detects whether a value is of a particular type. Accepts a native (decoded) value and determines whether
* it matches the current Type object.
*/
is: function (myDateValue) {
return angular.isDefined(myDateValue) && this.decode(myDateValue) === myDateValue;
}
})
}
}(this.angular, this.Date));
so, now you can say something like:
$stateProvider
.state('messagelogs', {
controller: 'Messages',
url:'/messageLogs/{pageIndex:int}/{itemsPerPage:int}/{text:string}/{fromDate:myDate}
});
and when you want to pass date, you can say:
$state.go('messagelogs', {fromDate: (new Date()).toISOString()})
or if you provide encode function that creates string from Date:
$state.go('messagelogs', {fromDate: new Date()})
You can find more on:
http://angular-ui.github.io/ui-router/site/#/api/ui.router.util.type:Type

Related

`RxJS` throws error on subcribe when do request

I am making a request using observable. and trying to subcribe the value. But getting error on typescript. any on help me?
I like to do this:
public getCountry(lat,lan):Observable<any>{
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false').subscribe(data => {
return this.genertedData(data);
} );
}
But getting error as follows:
UPDATES
public getCountry(lat,lan):Observable<any>{
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false').map( data => {
data.results.map( array => {
let details = array.address_components.find( obj => obj.types.includes("country") );
this.countryDetails.countryLongName = details.long_name;
this.countryDetails.countryShortName = details.short_name;
})
return this.countryDetails;
})
}
The problem is that your return type states Observable<any>, where as you actually return whatever this.genertedData(data) returns (Hint: Sounds like a typo in your function. Guess it should be called generatedData ?).
Best practice would be to move the http call into a service and subscribe to its returned Observable within your component.
So to speak:
// => service.ts
public getCountryObservable(lat,lan):Observable<any> {
return this.http.get(this.googleApi+lat+','+lan+'&sensor=false');
}
Your component would look something like:
// => component.ts
export class YourComponent {
constructor(public yourService: YourService) {}
getCountry(lat, lan): whateverDataTypeYourGeneratedDataReturns {
this.yourService.getCountryObservable(lat, lan).subscribe((data) => {
this.data = this.generatedData(data);
});
}
}
Since the return type of the function is Observable<any>, I guess it should just return this.http.get(this.googleApi+lat+','+lan+'&sensor=false')

How to put many parameters in a route in FOSJsRoutingBundle?

I have a route with many parameters; but when I generate it with FOSJsRoutingBundle the navigator takes just the first parameter and generate a 404 Error
Example:
var id = $(this).val();
var name = "aaa";
$.ajax({
url: Routing.generate('my_route', {
'id': id,
'name': name
}),
// rest of code
This syntax is it correct ?
EDIT 1 :
My route
my_route:
path: /homepage/{id}/{name}
defaults: { _controller: AcmeBundle:Personal:changename}
options:
expose: true
Just incase someone else comes across this (I just wasted several hours)... If the parameter you are passing in matches the default, Routing.generate doesn't include the parameter.
For example:
Controller:
/**
* #Route("/plc/data/{systemID}/{tagID}", name="web_plc_data", options = { "expose" = true })
*/
public function indexAction(Request $request, $systemID=1, $tagID=16)
{
}
From twig:
var url = Routing.generate('web_data', { systemID: 10, tagID: 16 });
Will generate route:
/plc/data/10 (note 'tagID' parameter is ignored)
From twig:
var url = Routing.generate('web_data', { systemID: 10, tagID: 17 });
Will generate route:
/plc/data/10/17 (tagID parameter now included as it doesn't match default)
Best solution I could find was to set default parameters to NULL in the route, then initialise in the function itself (if null, set to some value).
Ie:
/**
* #Route("/plc/data/{systemID}/{tagID}", name="web_plc_data", options = { "expose" = true })
*/
public function indexAction(Request $request, $systemID=null, $tagID=null)
{
if ($systemID==NULL)
{
$systemID = 1;
}
if ($tagID==NULL)
{
$tagID = 16;
}
}
Implementation makes sense, just a bit confusing as it causes unexpected behavour.
I don't know why the navigator doesn't take the second parameter but i have solved the problem like this :
var id = $(this).val();
var name = "aaa";
var url = Routing.generate('my_route', {
id: id,
}) + "/" + name;
$.ajax({
url: url,
// rest of code
In case someone else is dealing with the same issue, I just added the option expose true to the route since i'm using FOSJsRoutingBundle to generate the route in javascript, and everything work fine.
Here is the route definition:
/**
* #Route("/show/{id}/{toValidate}", name="contribution_show", methods={"GET"}, options={"expose"=true})
*/
public function show(Contribution $contribution, $toValidate): Response
And here is my ajax call to generate the route:
url : Routing.generate('contribution_show', {id: id, toValidate: toValidate }),

Play framework show States list from DB based on selected Country Id using AJAX

I am a newbie to Play Framework with Scala. Currently in my project's registration form I have options of Country and States in Drop down. I need to show the States list for the selected Country. Using an AJAX call for this purpose I have used the below code snippet. But it shows
Cannot write an instance of Seq[(String, String)] to HTTP response.
Try to define a Writeable[Seq[(String, String)]]
What I tried
addStudent.scala.html
<div>
Country:
#select(
studentForm("country"),
countryList,
'_default -> "-- Choose Country --",
'onChange->"ajaxCallforStateList(this.value)")
</div>
<script>
function ajaxCallforStateList(countyid) {
ajaxCall(countyid);
var testAjax = jsRoutes.controllers.Students.ajaxCall(countyid);
$.ajax({
url : testAjax.url
});
}
var ajaxSuccess = function(action, data) {
$("body").append("<br/>");
$("body").append(action + " " + data);
};
var ajaxError = function(action, error) {
alert(action + " : " +error);
}
function ajaxCall(countyid) {
var ajaxCallBack = {
success : onSuccess,
error : onError
}
jsRoutes.controllers.Students.ajaxCall(countyid).ajax(ajaxCallBack);
};
var onSuccess = function(data) {
alert(data);
}
var onError = function(error) {
alert(error);
}
</script>
JavascriptRoute.scala
package controllers
import play.api.Routes
import play.api.mvc.Action
import play.api.mvc.Controller
import play.api.mvc.EssentialAction
import play.core.Router.JavascriptReverseRoute
import play.core.Router._
import routes.javascript.Application.index
import routes.javascript.Students.ajaxCall
object JavascriptRoute extends Controller {
/* Application related JavascriptReverse Route will goes here */
val appRoutes: List[JavascriptReverseRoute] = List(index, ajaxCall)
/* All JavascriptReverse Route will combine here */
val javascriptRouters = appRoutes
/**
* This is use to generate JavascriptReverseRoute for all provided actions
*
* #return
*/
def javascriptRoutes: EssentialAction = Action { implicit request =>
import routes.javascript._
Ok(Routes.javascriptRouter("jsRoutes")(javascriptRouters: _*)).as("text/javascript")
}
}
routes
GET /ajax-call/:countryId controllers.Students.ajaxCall(countryId:String)
#Javascript Routes
GET /javascriptRoutes controllers.JavascriptRoute.javascriptRoutes
Students.scala
def ajaxCall(countryId:String) = Action { implicit request =>
Ok(stateList.options(countryId))
}
Student.scala
case class stateList(stateid:Option[Int] = None,
statename: String)
object stateList{
val simple = {
get[Option[Int]]("state.STATE_ID") ~
get[String]("state.STATE") map {
case stateid~statename => stateList(stateid,statename)
}
}
def options(countryId:String): Seq[(String,String)] = DB.withConnection { implicit connection =>
SQL("select * from state WHERE COUNTRY_ID = {countryid}")
.on('countryid->countryId)
. as(stateList.simple *).
foldLeft[Seq[(String, String)]](Nil) { (cs, c) =>
c.stateid.fold(cs) { id => cs :+ (id.toString-> c.statename) }
}
}
}
You're attempting to render a Seq[(String,String)] (from stateList.options(countryId)) as the body of an Action, but you haven't told Play how to serialize it. You could define a Writeable (https://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.http.Writeable) to tell Play how to convert your Seq into something your client will know how to read. Presumably you're looking for a simple string, so either your Writeable wants to be a very simple conversion, or you could even change Ok(stateList.options(countryId)) to be Ok(stateList.options(countryId).mkString("[",",","]")).
According to your existing code and if I understood the question correctly, a quick way to output a JSON would be
OK(JsArray(stateList.options(countryId).map{case (id, name) =>
JsObject(Seq(
"id" -> JsString(x.id),
"name" -> JsString(x.name)
))
}))

How can I can the scope which the onComplete function is called

I have created a wrapper for the FineUploaderBasic class in order to link it in with my existing system and when the onComplete function is called it is called in the scope of the FineUploaderBasic element and not the parent element.
How can I change this or access the parent of the FineUploaderBasic Instance?
I have written the code using ExtJs as Follow's and I am trying to trigger my own upload complete event once the FineUploader upload has been completed. but the "onUploadComplete" function is being called within the scope of the FineUploader Instance and I am not able to access my own object.
Ext.define('X4.Core.FileUploader', {
mixins: {
observable: 'Ext.util.Observable'
},
uploader: null,
constructor: function (config) {
this.initConfig(config);
this.mixins.observable.constructor.call(this, config);
this.addEvents({
/**
* Event which is triggered once the file upload has been completed successfully.
*
* #since X4 4.1.1
*/
"uploadcomplete": true
});
return this;
},
getUploader: function () {
var me = this;
if (me.uploader === null) {
me.uploader = new qq.FineUploaderBasic({
autoUpload: false,
request: {
endpoint: '/_system/x4/commands/file_uploader.ashx'
},
callbacks: {
onComplete: me.onUploadComplete
}
});
}
return me.uploader;
},
onUploadComplete: function(id, name, response) {
var me = this;
alert('upload complete ' + id + ' ' + name + ' ' + response);
me.fireEvent('uploadcomplete', me.callbackScope, id, name, response);
},
addFile: function (fileInput) {
var me = this;
return me.getUploader().addFiles(fileInput.extractFileInput());
},
upload: function () {
var me = this;
me.getUploader().uploadStoredFiles();
}
});
Since you haven't provided any specific information about your problem, I'm going to have to provide a very generic answer. Also, since you have not specified if you are using the jQuery plug-in or not, I'll have to assume that you are not.
So, the answer to your question really has nothing to do with Fine Uploader. Assuming you are using the no-dependency version, Fine Uploader sets the context of the call to each callback/event handler to the associated Fine Uploader instance. You are asking for the "parent" element, ostensibly the parent element of the value you have specified for the element option.
You can determine the parent of any element/node via the node's parentNode property.

Codeigniter rest issue with backbone

I just started using rest library wrote by Phil Sturgeon. I started using it by writing some simple examples. I short of get 'post' and 'get' work, but not for put and delete. I have some questions based on the code below.
// a simple backbone model
var User = Backbone.Model.extend({
urlRoot: '/user',
defaults:{
'name':'John',
'age': 17
}
});
var user1 = new User();
//user1.save(); // request method will be post unless the id attr is specified(put)
//user1.fetch(); // request method will be get unless the id attr is specified
//user1.destroy(); // request method will be Delete with id attr specified
In my CI REST controller
class User extends REST_Controller
{
public function index_get()
{
echo $this->get(null); //I can see the response data
}
public function index_post()
{
echo $this->post(null); //I can see the response data
}
public function index_put()
{
}
public function index_delete()
{
}
}
Basically, the get and post in the controller will be called when I save a model or fetch a model. With a id specified in the model, I can make a put or delete request to the server using model.save() and model.destroy(). however, I got a server error. it looks like index_put or index_delete can not be called. does anyone know How I can handle:
put request in the controller
delete request in the controller
get a single record with id specified
From the git, I only saw him to list index_post and index_put. there is no index_put and index_delete demo. should anyone can help me out? thanks
I faced the same exact problem, it looks like that DELETE, PUT, PATCH methods are not fully supported by browsers/html/server yet. You may want to look at this stack overflow question: Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
A simple solution would be to change the methodMap of backbone line 1191 to the following:
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'POST', //'PUT',
'patch': 'POST', //'PATCH',
'delete': 'POST', //'DELETE',
'read': 'GET'
};
and then include the action type as an attribute of the model
var Person = Backbone.Model.extend({
defaults:{
action_type : null,
/*
* rest of the attributes goes here
*/
},
url : 'index.php/person'
});
now when you want to save a model, do the following
var person = new Person({ action_type: 'create' });
person.set( attribute , value ); // do this for all attributes
person.save();
in the application/controllers folder you should have a controller called person.php with class named Person extending REST_Controller, that has the following methods:
class Person extends REST_Controller {
function index_get() { /* this method will be invoked by read action */ }
/* the reason those methods are prefixed with underscore is to make them
* private, not invokable by code ignitor router. Also, because delete is
* might be a reserved word
*/
function _create() { /* insert new record */ }
function _update() { /* update existing record */ }
function _delete() { /* delete this record */ }
function _patch () { /* patch this record */ }
function index_post() {
$action_type = $this->post('action_type');
switch($action_type){
case 'create' : $this->_create(); break;
case 'update' : $this->_update(); break;
case 'delete' : $this->_delete(); break;
case 'patch' : $this->_patch(); break;
default:
$this->response( array( 'Action '. $action_type .' not Found' , 404) );
break;
}
}
}
Having said that, this solution is an ugly one. If you scroll up in the backbone implementation, you will find the following code at line 1160:
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
which means you need to set the emulate options of backbone configurations. add the following lines to your main.js
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
To test the effect of that, I created a simple model and here are the results
you need a controller called Api in applications/controllers folder, in a file named api.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
require_once APPPATH.'/libraries/REST_Controller.php';
class Api extends REST_Controller
{
function index_get()
{
$this->response(array("GET is invoked"));
}
function index_put()
{
$this->response(array("PUT is invoked"));
}
function index_post()
{
$this->response(array("POST is invoked"));
}
function index_patch()
{
$this->response(array("PATCH is invoked"));
}
function index_delete()
{
$this->response(array("DELETE is invoked"));
}
}
and in your js/models folder, create a model called api_model.js
var Api = Backbone.Model.extend({
defaults:{
id: null,
name: null
},
url: "index.php/api/"
});
var api = new Api();
api.fetch({ success: function(r,s) { console.log(s); } }); // GET is invoked
api.save({},{ success: function(r,s) { console.log(s); } }); // POST is invoked
//to make the record old ( api.isNew() = false now )
api.save({id:1},{ success: function(r,s) { console.log(s); } }); // PUT is invoked
api.destroy({ success: function(r,s) { console.log(s); } }); //DELETE is invoked
I don't know how to do patch, but hope this helps.
Edit
I found out how to do patch, which is not included in the REST implementation of code ignitor. In REST_Controller line 39, you will find the following,
protected $allowed_http_methods = array('get', 'delete', 'post', 'put');
you need to add 'patch' at the end, to accept this method, also, after doing that add this code
/**
* The arguments for the PATCH request method
*
* #var array
*/
protected $_patch_args = array();
also, you need to add the following code to parse patch arguments:
/**
* Parse PATCH
*/
protected function _parse_patch()
{
// It might be a HTTP body
if ($this->request->format)
{
$this->request->body = file_get_contents('php://input');
}
// If no file type is provided, this is probably just arguments
else
{
parse_str(file_get_contents('php://input'), $this->_patch_args);
}
}
Now, according to backbone docs, you need to pass {patch: true} to send a PATCH method, when you call the following line, you execute a patch:
api.save({age:20},{patch: true, success: function(r,s) { console.log(s); } });
// PATCH is invoked

Resources