How can I cause a state to be refreshed with ui-router? - angularjs

I am on the state:
home.subjects.subject.exams.exam.tests.test
I delete a test and retrieved a new list of tests without the test I deleted in response.data.tests.
So now I want to go to this state:
this.$state.go('home.subjects.subject.exams.exam.tests', {
examId: this.exs.exam.examId,
subjectId: this.sus.subject.id,
tests: response.data.tests
});
But the router is thinking I already got all the resolves for the state so it does not try to repopulate the new list of tests.
Can someone tell me if it's possible to go to a state like this but have the resolves work.
Hope this makes sense.

There is an additional param that you can pass to go:
this.$state.go('home.subjects.subject.exams.exam.tests', {
examId: this.exs.exam.examId,
subjectId: this.sus.subject.id,
tests: response.data.tests
}, {
reload: true
});
See http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state for more details

Related

How can I save my data using localStorage in AngularJS?

I am working on a To-Do list app and would like to save data on the local storage of the device, but I can't figure out what it is I need to do.
In my app.js file I have the following code which allows me to add new tasks and to edit them:
.controller('DashCtrl', function($scope, $ionicPopup, $ionicListDelegate) {
$scope.tasks =
[
{title:"Example 1", completed: true},
{title:"Example 2", completed: false},
];
$scope.newTask = function(){
$ionicPopup.prompt({
title:"New Task",
template: "Enter task:",
inputPlaceholder:"Please add your task",
okText:'Create task'
}).then(function(res){
if (res) $scope.tasks.push({title: res, completed: false});
})
};
$scope.edit = function(task){
$scope.data = { response: task.title};
$ionicPopup.prompt({
title: "Edit Task",
scope: $scope
}).then(function(res){
if(res !== undefined) task.title = $scope.data.response;
$ionicListDelegate.closeOptionButtons()
})
};
The data is stored in the scope so I tried the following:
localStorage.setItem(scope));
And my idea is to call this function every time a new task is added, so that the storage is always up to date. But this does not seem to be working, what am I doing wrong?
This is the way to go:
https://github.com/gsklee/ngStorage
"An AngularJS module that makes Web Storage working in the Angular Way. Contains two services: $localStorage and $sessionStorage."
localStoragestores strings. If your data is already a string, a simple
localStorage.setItem($scope.data) should work. If it's a valid JSON, you stringify it and store as before.
localStorage.setItem(JSON.stringify($scope.data))
#Ladmerc would this work?
$scope.newTask = function(){
$ionicPopup.prompt({
title:"New Task",
template: "Enter task:",
inputPlaceholder:"Please add your task",
okText:'Create task'
}).then(function(res){
if (res) $scope.tasks.push({title: res, completed: false});
localStorage.setItem(JSON.stringify($scope.data));
localStorage.setItem($scope.data);
})
};
I think there are multiple issues with your approach, first being that you are trying to save the whole $scope object, you can place a console.log() to see how much data it contains, spoiler alert, a lot. The $scope object can be huge and there is no need to save it, what you want is to save the tasks. As mentioned by others, you also need to stringify your data, because localStorage only accepts strings. Luckily you don't have to solve these issues yourself, I would highly recommend you take a look at localForage, it is a library that:
localForage is a fast and simple storage library for JavaScript.
localForage improves the offline experience of your web app by using
asynchronous storage (IndexedDB or WebSQL) with a simple,
localStorage-like API.
You can find more information about localForage in the documentation and there is also an Angular wrapper available.
In your case, this would be an example of how to use this library:
$localForage.setItem('tasks', $scope.data).then(function() {
console.log("The tasks have been saved!");
});

Adding new data to a state in react.js

I working on a project where I am using react.js with laravel where I am using react for adding new comment in a post for that I am trying to to react's state but I want to add new data retrieved from server in my state without deleting or erasing old data present from that state. How can I achieve that method, is there any dependency for that, or any example or tutorial for that? Even If I am going with wrong approach then also please tell me what approach will be perfect.
The sample code for my problem -
I've an ajax function to get data initially.
getData: function() {
$.ajax({
url: '/get-data',
dataType: 'json',
cache: false,
success: function(data) {
this.setState({
data: data
});
}.bind(this)
});
}
and now after triggering new event I want to update my state without loosing my old data.
Thank you.
You should use the react immutability helpers
This allows you to update nested parts of the state without having to reset the whole thing. If you are just manipulating the root level properties of the state (e.g. this.state.blah or this.state.foo) then this.setState({ foo: 'a value'}); will leave the other root elements as they were.
If you do then want to completely reset the state you can use replaceState({});
setState
replaceState
If data in your code is a valid JSON object, you can use something like:
object-assign
lodash.merge
to merge your data before setting it to state.data. An example using lodash.merge:
import merge from 'lodash.merge'
// some of your code
// inside your getData function in your components
$.ajax({
success: function (data) {
this.setState({
data: merge({}, this.state.data, data)
});
}.bind(this)
});
Whilst it may be not a good practice to be doing this sort of wholesome replacement, it should address your issue. What might be a better approach is not really a scope of this answer :D

Ui-Router $state.go() does not refresh data

I have a Product List state and Product Edit/Add state in my Angular app.
Product List data gets loaded in the controller (I didn't think I need resolve to be defined in state config) which gets data from an ngResource:
function InventoryListCtrl (myResource) {
var vm = this;
myResource.query(function (data) {
vm.products = data;
});
}
On Edit Controller, after I edit a product I get back to list state like this:
vm.product.$update().$promise;
$state.go('productList');
It doesn't load list with new data always, it shows old data in first run generally, then after I do second update and manually get back to list state it starts to refresh after each update.
I've tried this, but didn't work either:
vm.product.$update().$promise;
$state.go('productList', {}, { reload: true });
What am I missing?
I think you're loading the new state before the update has completed - try moving the state transition to after the update completion:
vm.product.$update().then(function(){
$state.go('productList', {}, { reload: true });
});
i think this should work for current state refresh.
$state.go($state.current, {}, {reload: true}); //second parameter is for $stateParams
I had the same problem with a list not refreshing after edit. Wrapping the $state.go in a $timeout function solved my problem.
$timeout(function(){
$state.go('publishers.list', {}, { reload: true });
},200);

Destroy Backbone model using async=false

I try to pass {async: false} to the destroy function of my model but it doesn't work:
m.destroy({
async: false,
success: function(){
console.log('destroyed');
}
});
console.log('already destroyed');
I see the second log before the first one. Am I missing something or async doesn't work for destroy?
Please look for my project which was created for testing Backbone-Debugger (Chrome plugin)
https://github.com/piecioshka/test-backbone-debugger
Please let me know, if it's helpful!

How to prevent backbone router to call event on page load

I am a bit confused at the moment. My routes functions are being executed on the first load, which is not good in my case, because I am rendering the content with these functions and on the first load I am getting the duplicated content... Ok, I can add the control variable to prevent rendering on first init, but I would like to do it with pure backbone...
Here is my code:
var Router = Backbone.Router.extend({
routes: {
"": "home",
"home": "home",
"about": "about",
},
home: function(){
getContent("home")
},
about: function(){
getContent("about")
},
initialize: function(){
Backbone.history = Backbone.history || new Backbone.History({silent:true});
root = "kitchenV3/"+lang;
var enablePushState = true;
var pushState = !! (enablePushState && window.history && window.history.pushState);
Backbone.history.start({
silent: true,
pushState: pushState,
root: root
});
}
});
On the other side, if i remove ,,home" and ,,about" methods and write them this way, they are not executed on the first load. But what is the actual difference between these two? Is it possible to write the code like on the first example, but to prevent execution on the first load?
router.on('route:home', function(id) {
getContent("home")
});
Thank you for all answers...
From Backbone's doc:
"If the server has already rendered the entire page, and you don't want the initial route to trigger when starting History, pass silent: true."
As for the difference between your 2 examples: when you start Backbone's history in the second case, no routes are bound, so obviously no code is executed.
Edit:
Successfully tested.
You'll have an alert. Then replace Backbone.history.start() by Backbone.history.start({silent: true}) and nothing will happen.
Furthermore, digging into Backbone.history#start:
if (!this.options.silent) return this.loadUrl();
So... I don't know, but if it doesn't work for you, I'll guess we'll need more information.
Edit 2:
I've changed what I told you in the comments, and this is the result. Once again, simply remove the silent: true to see the difference.

Resources