I have a Message model with a value and author properties. I can do this inside the Ember codes (controller, model, views, etc):
this.store.push('message', msgObj)
However, the following does not work at the Global scope, say putting that inside <script src="websocket_processor.js"> like:
msgObj = {value: 'Hello!', author: 'Jules'}
//I've tried the following but does not work
this.store.push('message', msgObj) //`this` doesn't point to ember
store.push('message', msgObj) //Console error: undefined store
App.Store.push('message', msgObj) //Uncaught TypeError: Object function () {if (!wasApplied) {...
I want this to be outside ember because I am using websocket-rails gem from which I use the following function
dispatcher.bind('add_message', function(data) { //add_message is just a method param from server
//Code where I need to use Ember to store say
this.store.push('message', data)
}
I'm stuck with this for hours now. Any help would be appreciated. Thanks!
You can use Application initializer to do the job and lookup for store after it has been registered so you can use it in external component.
Ember.onLoad('Ember.Application', function (Application) {
Application.initializer({
name: "websocket-rails",
after: "store",
initialize: function (container, application) {
var store = container.lookup('store:main');
// Now you can inject store to component outside of Ember
}
});
});
Related
how to get work Fetch API with Rails and React.
Setup: Rails 5, Sprockets and React from Webpacker.
What I'm trying to achieve here is use Fetch API to fetch and load data to ReactBootstrapTable API.
import React from 'react';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import 'whatwg-fetch'
class ExampleTable extends React.Component {
constructor() {
super();
this.state = {
datatable: [], // I'm not sure if I can use array to json data.
};
}
// I'm new to React, so I'm not sure if I'm passing props right
componentDidMount() {
console.log('start componentDidMount');
fetch('https://www.test.com/test.json')
.then(function(response) {
return response.json();
}).then(function(response) {
let datatable = response;
this.setStates({ datatable });
}).catch(function(ex) {
console.log('parsing failed', ex);
});
}
render() {
return (
<div>
<BootstrapTable
data={this.states.datatable} //Here, I'm passing data to the table
pagination
striped hover condensed
options={ { noDataText: 'Empty Table' } }>
<TableHeaderColumn isKey dataField='id' width='80px' dataAlign='center'>
ID
</TableHeaderColumn>
<TableHeaderColumn dataField='test'width='300px' dataAlign='left'>
Test
</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default ExampleTable;
The main problem here is that I'm not able to use Fetch API and also I'm not totally sure about the way I'm passing data to the table (basically how to use react)
I'm getting a error/warning from my IDE
fetch is not defined
And another error message from the Firefox console:
The above error occurred in the component: in ExampleTable
TypeError: this.states is undefined
I installed the Fetch API through yarn and checked the node_modules/whatwg-fetch folder. As described from the github API, I imported 'whatwg-fetch' as showed in the code above.
I don't know what else I should do. I installed ReactBoostrapTable in the same way and got succeeded doing it. Everything else is working fine.
I looked at the installation instructions of fetch for use with webpack, it says to add this to your webpack configuration:
entry: ['whatwg-fetch', ...]
Also, you mentioned the other error TypeError: this.states is undefined. It looks like you have a typo. In React, if you're trying to refer to state, you use it like this:
this.state.datatable
In your render method, you refer to this.states.
Also, when you're making your call with fetch, you're trying to call this.setStates. You should instead be using it like this:
this.setState({ somestate: "xyz"})
I'm currently working on an ASP.NET MVC project to which some AngularJS was added - including some AngularJS directives.
I need to add to an AngularJS directive a MVC partial view. Obviously,
#Html.Partial("_PartialView", {{name}})
doesn't work.
So far all my searches online provided no help.
Any idea how I could render a partial view inside an Angular directive?
Thanks!
Angular exists strictly on the client side whereas MVC views exist on the server side. These two cannot interact directly. However, you could create an endpoint in which your partial view is returned as HTML. Angular could call this endpoint, retrieve the HTML, and then include it inside a directive.
Something like this:
app.directive("specialView", function($http) {
return {
link: function(scope, element) {
$http.get("/views/partials/special-view") // immediately call to retrieve partial
.success(function(data) {
element.html(data); // replace insides of this element with response
});
}
};
});
app.directive("myDirective", ['', function () {
return {
restrict: 'A',
scope: {
foo: '='
},
templateUrl: '/home/_myDirectivePartialView',
}]
} }]);
Just need to use templareURL and specify the route to get the partial view.
I'm working on an asp.mvc3 web api project. in this project I use TypeScript and Angular.js
and I need to access the business layer from TypeScript through the Web API. I called the Web API inside the constructor method in TypeScript using the
code given below.
constructor($scope, $http: any) {
$scope.VM = this;
$http.get("/API/PrivateAPI/Test/1").success((a) => { this.Tiles = a });
var bb = this.Tiles;
}
However, when trying to get the object list from the business layer, the Tiles array is empty. I debugged the code and found out the Web API is called after passing the last line of the constructor and does return results. I need to call that method inside the constructor and get object list to the Tiles array.
Does anyone know how to do so?
First of, I think you should do the following (notice .data) :
$http.get("/API/PrivateAPI/Test/1").success((response) => { this.Tiles = response.data });
Anyways, $http only supports async http requests. What you want can be done by a synchronous XHR request and that is considered bad UI experience, since the browser window freezes till the XHR request completes, and therefore $http doesn't support it (configuration docs).
What you can do is something like :
call another function from response e.g.
(response) => { this.Tiles = response.data; this.continueWithProcessing(); }
Or, Setup a variable to hide a preloader when the response comes back:
(response) => { this.Tiles = response.data; this.allDone=true; }
Where you have an ng-show on something like:
<div ng-show="!VM.allDone">Loading the data....</div>
Or both :)
Note: An async setting is supported in underlying browsers native XHR object and therefore in $.ajax which is the jquery ajax function : http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings. However it is a horrible UI experience + if you use it from angular you are responsible for scope.apply.
I have my Rails and Backbone.js application deployed to a suburi. What is the best way to prepend all request with the suburi?
Example: application is deployed to www.example.com/app. I have a resource users and I'd like backbone to call www.example.com/app/users instead of the default www.example.com/users.
I'm setting a ROOT_URI variable on the server side and I'm going to use it in the backbone app. The simple way is to add it to all urls in models and collections, but it's tedious and error prone. What should I do? Override Backbone.sync?
you can pass URL on your Fetch call
Example
model.fetch({
url: yourServiceURL,
success: function (response, xhr)
{
//console.log("Successfully Fetched...");
},
error: function()
{
//console.log("Error Occurred...");
}
});
in this way you don't have to define url in your model and collections
EDIT
what i understand from your comment. you can do something like this
yourModel = Backbone.Model.extend({
url:function() {
return yourGlobalVarForRootURI+"/staticLogicalPathForEachModel";
},
parse: function (response) {
return response;
}
});
in this way you can give yourGlobalVarForRootURI variable in all of your models/collections and you can change this global variable so it will be changed in all models/collection. I hope it will solve your problem
Ok. I have a url setup to log a user out. On the server, there is no html. The session on the server simply gets destroyed, and then the user is redirected to an address.
This works fine with plain html, but with Angular i am having issues. I've been routing all main routes using $routeProvider.when('/foo', {templateUrl: '/foo.html', controller: 'Ctrl'}) and that works fine for normal templated routes.. however, if there is no template it will not work.
So, how do i support the route /logout in the same fashion as above, when there is no html template?
A workaround is to use template instead of templateUrl. From the Angular docs:
template – {string=} – html template as a string that should be used
by ngView or ngInclude directives. this property takes precedence over
templateUrl.
This can be used as follows:
$routeProvider.when("/foo", {template: " ", controller: "Ctrl"});
Note: You must use " " instead of an empty string "" because Angular uses an if (template) check before firing the controller, and an empty string evaluates to false.
-- EDIT --
A better way to do it is to use the resolve map. See the Angular Docs:
resolve - {Object.=} - An optional map of
dependencies which should be injected into the controller.
This can be used like this:
$routeProvider.when('/foo', {resolve: {redirect: 'RedirectService'}});
Note: I've changed it from "Ctrl" to "RedirectService", because what you're describing in the question isn't really a "controller" in the Angular sense. It doesn't set up scope for a view. Instead, it's more like a service, which ends up redirecting.
I am writing the solution based on the already accepted answer and the github issue mentioned in it's comments.
The approach I am using is a resolve parameter in the $routeProvider. In my case I was trying to create a nice solution to logout in my application, when user goes to /logout.
Example code of $routeProvider:
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
...
when('/logout', {
resolve: {
logout: ['logoutService', function (logoutService) {
logoutService();
}]
},
}).
...
}]);
In the resolve part you specify a service (factory) by name and later on you have to call it. Still it is the nicest solution around.
To make the example complete I present my logoutService:
angular.module('xxx').factory('logoutService', function ($location, Auth) {
return function () {
Auth.setUser(undefined);
$location.path('/');
}
});
Works great!