Using fetch API to get data from Rails - ruby-on-rails

So I am building a react on rails project to learn some new things. I am trying to use the fetch API to get data from the db.
I have tried this method and this one. But I might be implementing them wrong.
This is my fetch route:
fetch('/get_data')
.then(response => {
response.json();
})
.then(data => console.log(data));
I have my route set up in Ruby on Rails:
match '/get_data' => 'get_data#pull', via: :get
I have my controller just doing something simple at the moment to see if I can get any data.
class GetDataController < ApplicationController
def pull
#allproduct = Product.all
render json: #allproduct
end
end
Thanks for any help in pointing me in the right direction!

The issue was that I needed a return statement in my fetch call. :)
fetch('/get_data')
.then(response => {
return response.json();
})
.then(data => console.log(data));

Related

Ruby on Rails api json response methods and include

I have technical question i have user model which have many questions so in my API controller i do:
render json: user, :include => {
:questions => {
:only => [:text]
},
}
Now i want to add to JSON response question count. How can i do that in best way. I know that i can create method inside model : count_question and after that do:
render json: user, :include => {
:questions => {
:only => [:text]
},
}, :methods => [
:count_question
]
and my response will be good. But is there better way to put that information to JSON. I want to avoid add method inside model. Is it possible to determine this count inside json renderer?
Greetings
Checkout JSON API and Active Model Serializers with Rails
This will hep you out format your JSON.

DELETE request, react + flux + rails

I want to create a simple twitter_clone. Now I'm trying to add a feature to be able to unfollow a user.
What I've done until now:
User can follow other user (I did it through Flux pattern)
I've done it this way:
followUser(userId){
$.post("/followers", {user_id: userId})
.success(rawFollower => ServerActions.receivedOneFollower(rawFollower))
.error(error => console.log(error));
},
It sends a POST to /followers and a USER STORE is fetching this data to update itself.
Now I'm looking for the way how to delete it. I've tried to do it by:
unfollowUser(userId){
console.log ("API.unfollowUser");
$.delete("/followers", {user_id: userId})
.success(unfollowUser => ServerActions.removedOneFollower(unfollowUser))
.error(error => console.log(error));
}
but it doesn't work. I've received an error:
Uncaught TypeError: $.delete is not a function
Basically, I try to remove one row from database and accordingly json connected with it and Later to update a STORE (delete this json from array which I use to determine a state of React Element)
This is destroy action from Rails followers controller:
def destroy
follower = Follower.find(user_id: params[:user_id],
followed_by: current_user.id)
follower.destroy
end
Could someone help me?
As you can see, the error you're getting is a Javascript error, not a Rails error.
There's no $.delete method for jQuery. Instead, you have to use the $.ajax one and specify the HTTP method, like so:
$.ajax({
url: '/followers',
method: 'DELETE',
data: { user_id: userId }
}).done(unfollowUser => ServerActions.removedOneFollower(unfollowUser))
.fail(error => console.log(error))
However, this might also fail because jQuery may not support sending data with a DELETE request, and that makes sense.
If you're using Rails and trying to be RESTful, you shouldn't be sending a DELETE request like this:
DELETE /followers
{ user_id: userId }
Rather, you should send a DELETE request like this:
DELETE /followers/:user_id
So to modify the code, it becomes like this:
$.ajax({
url: '/followers/' + userId ,
method: 'DELETE',
}).done(unfollowUser => ServerActions.removedOneFollower(unfollowUser))
.fail(error => console.log(error))
I haven't tried any of the code above, but It Should Just Work (TM).

Rails routes constraints based on model

Using Rails 3.1. I have the following in my route:
In my model Shop, I have a column called shop_type that has either boutique or saloon. Instead of having the url:
http://localhost/spots/1
I would like to separate it by the shop_type to:
http://localhost/boutique/1
http://localhost/saloon/2
So I added the following to my route:
resources :boutique, :controller => 'shops', :constraints => { :shop_type => 'boutique' }
resources :saloon, :controller => 'shops', :constraints => { :shop_type => 'saloon' }
The problem with this is I can access record ID 1 with shop_type = boutique with either of the URL. Ideally, it should return error when a user tries to access
http://localhost/saloon/1
But the above URL just works fine, which is not what I want.
Also, is there anyway to redirect all shops/1 to the new URL which is by shop_type?
Many thanks.
If you want to do this, then your application is probably telling you that it really wants two separate classes, Boutique and Saloon. Can you do that? If not, why not?
Maybe its better to tell Rails directo allow urls as:
get "/:shop_type/:id", :to => 'shop_controller#show'
And in controller check if the record exist, and return :status => 404 if not:
#shop = Shop.where(:id => params[:id], :shop_type => params[:shop_type]).first
render :status => 404 and return if #shop.nil?
Note that route provided is too greedy and put it after all other routes so it will not 'eat' other request.

Ruby on Rails 3.0 Pusher Chat

I'm trying to implement something similar to http://pusher-chat.heroku.com/
However, I cannot figure out how to call an action without the page refreshing.
The page refreshing defeats the purpose of using pusher.
So far I have created a chat table, with attributes account_id and message.
In my chat controller I have the following:
def create
account = Account.getAccountById(session[:user])
if params[:message].blank?
#title = "Chat"
#chatLog = Chat.find(
:all,
:order => "created_at ASC",
:limit => 20
)
render :action => :index
else
chatter = Chat.new(
:account_id => account.id,
:message => params[:message]
)
payload = {
"account_id" => chatter.account_id,
"message" => chatter.message
}
if chatter.save
Pusher['chat-channel'].trigger('send_message', payload)
#title = "Chat"
#chatLog = Chat.find(
:all,
:order => "created_at ASC",
:limit => 20
)
render :action => :index
else
render :action => :index
end
end
rescue ActiveRecord::RecordNotFound
reset_session
redirect_to(new_account_path)
end
In my chat.js file I have the following:
$(document).ready(function() {
// Enable pusher logging - don't include this in production
Pusher.log = function(message) {
if (window.console && window.console.log) window.console.log(message);
};
// Flash fallback logging - don't include this in production
WEB_SOCKET_DEBUG = true;
var pusher = new Pusher('62651eca256339fa7fca');
var channel = pusher.subscribe('chat-channel');
channel.bind('send_message', function(chatter) {
$('#loading').show();
});
});
I've never built anything like this before, so I would appreciate any help.
I know there has to be a lot more javascript involved.
Thank you,
Brian
To call an action without refreshing you should use ajax.
I haven't tried pusher yet but it seems that whenever someone "submits" a new message, your application, it shall send to the pusher channel so it can broadcast to every "subscribed" client online.
If this is correct, you should think the whole thing as this:
When someone clicks on "new chat" it will create a new chat room, instantiate a new channel on pusher and save it on database. This will generate the identification on the url, that you can send to someone so that they can join your chat.
On the chat screen, you will have one big div that will render the chat and on input text field where you send messages. This particular field will submit to your application using ajax your chat ID and the message.
On your chat controller when you receive this information, you go get the pusher channel id on database for that chat room, save message on database for history and send it back to every user connected on that room with pusher.
The logic to render the text on the chat will be done by client side javascript.
Hmmh, my approach would be to use a Javascript timer which calls an AJAX-script every two seconds to get the new chat entries since the last request - and then refresh only the chatbox. Like so:
var latest_entry_number = 0;
var chatter = window.setInterval("getNewestEntries()",2000);
function getNewestEntries() {
$.ajax({
url: "/path/to/latest_entries",
type: "POST",
dataType: "JSON",
data: {latest_entry: latest_entry_number}
success: appendEntries
});
}
function appendEntries(data) {
latest_entry_number = data.latest_entry;
$.each(data.entries, function(key,val){
//append the entries to the chat
})
}
And the controller action would look like this:
def latest_entries
data[:latest_entry] = get_latest_entry # each entry gets a consecutive, ascending number
data[:entries] = get_entries_since(params[:latest_entry_number]) # get all entries done since that number
# Should be an array
render :json => data
end
Or something like that.

Retrieving error data from a web service application

I am using Ruby on Rails 3 and I am trying to retrieve error data from a web service application after making to that an HTTP POST request. I would like to receive that data including the errors root.
In a service app controller I have
format.json {
render :json => #account.errors, :status => 202
}
The return data returned, for example, is
{\"base\":\"Invalid submitting\",\"name\":\"To short\"}
I would like to receive back data like this
# Note 'errors'
"{\"errors\":{\"base\":\"Invalid submitting\",\"name\":\"To short\"}"}
How can I make that?
A solution is to make this
render :json => '{"errors":' + #account.errors.to_json + '}'
but I don't think it is the right\correct way. RoR certainly has some features to do that better...
You should be able to construct an equivalent hash and then use that:
error_hash = { 'errors' => #account.errors.to_h }
render(:json => error_hash, :status => 302)

Resources