How to reset data of all the states : angularJs UI router - angularjs

.state('state1'
{
name :
url:
data:{
data1=[];
data2=[];
}
});
.state('state2'
{
name :
url:
data:{
data1=[];
data2=[];
}
});
Let us say I have n number of states.When user goes from one state to another
he is storing data into $state.current.data.
My question is , "is there any shortcut or any technique to reset the data for all the states again", let us say for the scenario when user logs out from the application , I want to reset the data .
I don't want to use $window.location.reload()
Any suggestions/help is appreciated!!
Thanks

You can use $state.get() to get all the configured states and then reinitialize the data object to a desired value.
Important: child states inherit the data property from their parent states - source. In order not to break the inheritance we'll use angular.copy.
This example reinitializes the data object with {}
angular.forEach($state.get(), function (state) {
angular.copy({}, state.data);
});
Note that there isn't any way to know the original value of the data object without explicitly specifying or storing it.

Related

Angular 1/ ui-router 1 - is it recommended to pass a large object in params?

My $state.go :
this.$state.go(transfer.project, params)
where prams is an object that contains a large project object and projectId property number type.
The state :
.state({
name: 'transfer.project',
url: '/{projectId:int}',
params: {
project: null
},
component: 'projectTransfer'
})
And I recover the object in my component with:
this.project = this.$state.params.project
is it a good practice to spend a large object in params ?
Or if you know where is the source code that this in ui-route library
The object is only being passed by reference, so all that's really happening is an additional pointer is being created to it. Resource usage would be very minimal.

Query arrays values with Firebase

Is there any way to on Firebae to filter data in an array?
I have this model on my Firebase:
-KABIGeWnBMUKjLTcvp8
deviceToken:"7DE60240CB4B712F05A009F32358610C1327917E7E68409..."
favorites
0:"Masha"
1:"moksha"
name:"juan"
And the problem is that I can't find any method to get all "users" that contain a certain value on the "favorites" array field.
Nope, that's not an option See firebase equivalent to sql where in ().
Instead: invert your data structure to make this query possible:
items_by_favorites
"Masha"
"-KABIGeWnBMUKjLTcvp8"
"moksha"
"-KABIGeWnBMUKjLTcvp8"
Now you can look up the item keys for Masha with a simple read: ref.child('items_by_favorites/Masha') and then load each item:
ref.child('items_by_favorites/Masha').on('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
ref.child('items').child(key).once('value', function(itemSnapshot) {
console.log(itemSnapshot.val());
});
});
})
First of all your question is answered deep in the guide for retrieving data, which is where I got this answer. It's under complex queries, then range queries, should you want more info.
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").equalTo(25).on("child_added", function(snapshot) {
console.log(snapshot.key());
});
The basic idea is that you need to first order the reference by a common child value, and then call .equalTo() to end up with a query that yields what you want.
Also you can call order by child like
ref.orderByChild("height/sublevel")
To drill deeper in the tree.
FirebaseFirestore.instance.collection('your collection name').where('favorite', arrayContains: 'Masha').snapshot();

Marionette Regions and routing

I'm using a LayoutView to display a collection in table form. When a user clicks on a tr I swap the CompositeView for an ItemView that shows the details using the same region. It all works except the functionality of the back button is broken. Is there a way to trap the back event and switch views?
Or should I use two Views and pass the model id and then refetch the model? The problem with that though is the extra request and I lose the filter and sort values of the table unless I use local storage.
Including more code would be better, but in any case I will try to give some guidance for your problem.
To avoid fetching the data twice, you can keep a common object in a "parent" component, for example in the Router.
var theObject;
var router = Marionette.AppRouter.extend({
routes: {
"routeA/:id": "goToRouteA",
"routeB/:id": "goToRouteB"
},
goToRouteA: function(id) {
MyRegion.show(new myLayout({
model: this._getCommonObject(id)
}));
},
goToRouteB: function(id) {
MyRegion.show(new myLayout({
model: this._getCommonObject(id)
}));
},
/*Return the common object for the views*/
_getCommonObject: function(id) {
theObject = (theObject && theObject.get('id') == id) ? theObject : MyApp.request('getTheObject');
return theObject;
}
});
In this way, you can keep the reference to the same object without loosing information.
You just have to make sure to delete the object when it is not needed to avoid keeping old information, for example on the Region close event.

Retrieving parent plus related children in one Parse REST API call

I'm building out a little app and the first thing I need to do is make a call to Parse's REST API using AngularJS's ngResource.
I've successfully constructed two Parse classes (let's call them "Parent" and "Child" for now) and set up a many-to-many relation between them such that a Parent can relate to zero-n Child objects and a Child may relate to zero-n Parent objects.
So far, the very basic stuff works fine. This method, for example, successfully retrieves all the Parent objects:
.factory('Parent', function($resource, appConfig) {
return $resource('https://api.parse.com/1/classes/Parent/:id', {}, {
list : {
method : 'GET',
headers: appConfig.parseHttpsHeaders
}
});
})
Awesome. It even has a "Child" attribute describing the relation (as you would expect) but does not return the actual Child objects inside each Parent.
Now I need to expand on this method to retrieve the related Child objects at the same time - I really don't want to have to make another call per Parent to get the related Child objects.
So we try this:
.factory('Parent', function($resource, appConfig) {
return $resource('https://api.parse.com/1/classes/Parent/:id', {}, {
list : {
method : 'GET',
headers: appConfig.parseHttpsHeaders,
params : {
'include' : 'Child'
}
}
});
})
...and the server returns...the exact same response as before. The Child records are not included.
Any ideas where I'm going wrong?
Edit: Note that while I've set up the Parent and Child relation already, I'm open to suggestions if this is not the best way of doing things if I need to query the data in this way. There will be a limited set of Parent objects (let's say under 100) and a much smaller set of possible Child objects (under 30).
The problem is the distinction between pointers and relations. Pointers can be eagerly fetched using include, but relations cannot. If the cardinality of the parent->child relationship is low, use an array of pointers instead of a relation and you'll get the results you expect/desire.
With help from danh, I've worked out how to get this set up in the way I wanted. Here's a little code snippet:
var cId = 'CHILD_ID';
var pId = 'PARENT_ID';
var Child = Parse.Object.extend("child");
var cQ = new Parse.Query(Child);
var Parent = Parse.Object.extend("parent");
var pQ = new Parse.Query(Parent);
pQ.get(pId, {
success: function (mResponse) {
console.log(pResponse);
cQ.get(cId, {
success: function (cResponse) {
console.log(cResponse);
pResponse.add('children', cResponse);
pResponse.save();
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
}
});
},
error: function (object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
}
});
First of all, create your two classes in the Parse.com data browser. Ensure that the Parent class has an Array column defined (in this case it was called 'children').
Add your parent object id and child object id to the relevant variables in the script and run it (obviously including your API keys at the top of the script). Hey presto! You will have an array of pointers for each relationship you run the script for.
Not only that, I can confirm that my AngularJS REST Api call returns the parent and child details in one call.

backbone.js not updating id of model object after save, why not?

I have been trying out backbone.js and have been stymied when I create a new model object then call model.save(). I am expecting the backbone.js default behavior to update the model object with the id from the database but it is not. Is this not supposed to happen? I have verified that I am getting a post with the attributes in json format. My server saves the json to a table and then returns the json with a new id field to backbone.js. Is this correct? Should my server return the entire new object or just the id or what?
//contents of the POST from backbone.js
{ "text":"this is a test" }
//reply from my server
{ id:"15", text:"this is a test" }
My sample code is below
var SQLRow = Backbone.Model.extend({
table:"",
urlRoot:'db',
url:function () {
return "/" + this.urlRoot + "?table=" + this.table +
"&id=" + this.attributes.id;
}
});
var Xtra = SQLRow.extend ({
table:'Xtra'
});
var row = new Xtra({
text: "this is a test"
});
alert(row.url());
row.save()
alert("row:" + row.get("id"));
Tough to tell from your post. Two ideas :
1) the response from the server isn't successful What does your save call return ?
2) Your "id" attribute is named something other than ID. To account for the different name add the following to your model :
idAttribute : "MyModelsID",
EDIT
You're likely facing a timing issue, where the alert fires before the ID has returned. Instead of your last two lines try this :
row.save( null,
{
success : function(model, response) { alert(model.get('id'); }
}
);
ALTERNATIVE
As #mu_is_too_short mentioned, another way is to listen for the change even on the model and respond to the event. (i was just trying to keep the answer as close to your code as possible). But something like the following pseudo code should get you started...
var myView = Backbone.View.extend({
....
initialize : function () {
this.collection.bind('change', this.SOME_LISTENING_FUNC );
}
});
OR, if you're in a collection/view-less world something like this creates a listenr ...
row.on('change', function() { /* do stuff */ }, this);
This answer is based on one comment of Cjolly in the answer above.
It is essential for making the Backbone.Model.save([attributes],[options]) successful in assiging the model with the newly generated model's id from the server, that the server returns the model's id in a JSON string like this { "id" : <the id> }. (note it is "id" and not id).
In essence backbone rightly expects a JSON string and in contrast to how objects may be defined in Javascript without quoted keys, JSON requires the object keys to be quoted (see JSON Spec - does the key have to be surrounded with quotes?)
Since according to Cjolly's comment this has been the essential problem, I want to hightlight this solution in an second answer. Partially because I was hit by the very same problem and only by reading througth the comments I was able to receive the insight.
I've faced the same issue and what I've found is that my validate function of the saved model actually invalidates the model returned from the back end. That's why my fields were not updated properly.
Maybe its a little outtimed, but today I had the same missing id.
It turns out, that the server just sends a Header 'Location' with a redirect containing the new id, but dosen't return the persisted object.
Adding the object to the response was the solution.
It seems, that not returning the object is standard behavier with Roo(Spring) generated Json-Controllers.

Resources