Sean Magyar
Sean Magyar

Reputation: 2380

ruby/rails JSON to hash then changing array of the hashes then send back JSON

I have a rails app. I get JSON from 3rd party API. I would like to modify it to be able to send the proper JSON to another API. I was able to make a hash of it with JSON.parse, but I can't modify the hash properly and I don't know the preferred way to turn it back to JSON then.

In the get_own_events method I have the result array (code works properly till this). Now I'm trying to extract some attributes and returning the new formatted_result array which only contains the necessary, formatted attributes (I don't need the original result array.).

How can return/create the proper formatted_result array of hashes and then turn it back to JSON? In the code at the moment I get back the original hash not the new hash what I'm trying to create.

controller

@google = @user.socials.where(provider: "google_oauth2").first
@results_own = get_own_events(@google)
respond_to do |format|
  format.html
  format.json { render json: @results_own }
end

method

def get_own_events(social_object)
  client = init_google_api_calendar_client(social_object)
  old_token = client.authorization.access_token
  service = client.discovered_api('calendar', 'v3')

  result_raw = client.execute(
    :api_method => service.events.list,
    :parameters => { 'calendarId' => social_object.email,
                     'timeMin' => "2015-12-27T00:00:00+00:00",
                     'timeMax' => "2016-01-30T00:00:00+00:00" },
    :headers => {'Content-Type' => 'application/json'})

  result = JSON.parse(result_raw.body)['items']

  formatted_result = result.each do |event|
    title = event['summary']
    if event['start']['dateTime']
      start_time = event['start']['dateTime'].to_datetime.rfc822
    end
    if event['end']['dateTime']
      end_time = event['end']['dateTime'].to_datetime.rfc822
    end
    if event['start']['date'] && event['end']['date'] && (event['start']['date'] != event['end']['date'])
      all_day = true
      start_allday_date = event['start']['date'].to_datetime.rfc822
      end_allday_date = event['end']['date'].to_datetime.rfc822
    end
    formatted_event = {}
    formatted_event['title'] = title
    formatted_event['start'] = start_time || start_allday_date
    formatted_event['end'] = end_time || end_allday_date
    formatted_event['allDay'] = all_day || false
    return formatted_event
  end

  return formatted_result
end

Upvotes: 1

Views: 199

Answers (2)

ezkl
ezkl

Reputation: 3861

If you are trying to populate a new collection, use map instead of each. So,formatted_result = result.each do |event| should be formatted_result = result.map do |event|.

formatted_result = result.map do |event|
  title = event['summary']
  if event['start']['dateTime']
    start_time = event['start']['dateTime'].to_datetime.rfc822
  end
  if event['end']['dateTime']
    end_time = event['end']['dateTime'].to_datetime.rfc822
  end
  if event['start']['date'] && event['end']['date'] && (event['start']['date'] != event['end']['date'])
    all_day = true
    start_allday_date = event['start']['date'].to_datetime.rfc822
    end_allday_date = event['end']['date'].to_datetime.rfc822
  end
  formatted_event = {}
  formatted_event['title'] = title
  formatted_event['start'] = start_time || start_allday_date
  formatted_event['end'] = end_time || end_allday_date
  formatted_event['allDay'] = all_day || false

  formatted_event
end

Upvotes: 1

MilesStanfield
MilesStanfield

Reputation: 4639

Changing .each to a .map may solve you're problem and go ahead and remove the return formatted_result at the end as you don't need it in Ruby because it's the last thing in your method and so

change this

formatted_result = result.each do |event|
  ...
  return formatted_event
end
return formatted_result

to this

result.map do |event|
  ...
  formatted_event
end

Upvotes: 1

Related Questions